簡體   English   中英

使用 React 鈎子防止 React 重新渲染 D3 圖表

[英]Using React hooks to prevent React re-rendering of a D3 chart

我一直在分別使用 React 和 D3,現在有一個項目,我需要對應用程序的繪圖功能進行低級別控制。 基本上,我需要能夠在用戶放大時從數據庫中獲取更高分辨率的數據,反之亦然。

我找到了幾種將 D3 和 React 結合使用的方法。 我想嘗試保留基於 hooks API 的所有 React 代碼,因為它用於其余代碼庫。 我正在努力為我面臨的特定情況獲得等效的鈎子。 React hooks 的文檔很棒,但我認為我的情況更像是一個邊緣案例,我沒有看到任何與我所擁有的類似用例相關的討論。

代碼的邏輯相當簡單:我有一個主容器,稱為 App.js,它保存一些狀態。 App.js 呈現一個 Wrapper 組件(這是發生挑戰的地方),然后 Wrapper.js 文件簡單地創建 D3 Plot。 D3 圖只是帶有一些縮放事件的線圖的典型 D3 代碼。

包裝器代碼:

import React, { Component } from 'react';
import Plot from './Plot'; // D3 plot

class Wrapper extends Component {

    // Sets up plot when Wrapper first added to DOM tree
    componentDidMount(){
        this.setState({
            plot: new Plot(this.refs.plot, this.props.data, this.props.updateData)
        });
    };

    // Do not allow React to re-render the Wrapper and therefore the Plot
    shouldComponentUpdate(){
        return false;
    };

    // When the data prop changes, execute the update() method in the plot file
    componentWillReceiveProps(nextProps){
        this.state.plot.update(nextProps.data) // the .update() method calls props.updateData()
    }

    render(){
        return <div ref="plot"></div>
    }
}

export default Wrapper;

我已經開始將下面的鈎子版本放在一起,但我無法提出合適的方法來滿足我對 shouldComponentUpdate 和 componentWillReceiveProps 塊的情況所追求的特定要求。

鈎子版本:

import React, { useEffect, useRef } from 'react';
import Plot from './Plot'; // D3 plot

const Wrapper = props => {

    // destruct props
    const { 
        data = props.data,
        fields = props.fields,
        click = props.click
    } = props

    // initialise empty ref
    const plotRef= useRef(null);

    // ComponentDidMount translated to hooks
    useEffect(() => {
        new Plot(plotRef, data, updateData)
    },[]) // empty array ensures the plot object is only created once on initial mounting

    // shouldComponentUpdate
    useEffect(...) // This won't work because render has already occurred before useEffect dependency array diffed?

    // ComponentWIllReceiveProps
    useEffect(() => {
        plot.update(data)
    }, [data]) // This won't work because component needs to have re-rendered

    return (
        <div ref= {plotRef}></div>
    )


};

export default Wrapper;

我想要實現的是在初始安裝后阻止 D3 圖表的任何渲染,但是如果父組件中的數據道具發生變化,則在 D3 類中執行一個方法,而不允許 React 重新渲染 Wrapper 組件。

這是可能的還是我最好將它作為基於類的組件?

我一直在用頭撞牆試圖獲得邏輯但沒有任何成功,因此任何輸入都將不勝感激。

您可以使用合適的依賴項將返回值包裝在 React useMemo 中。

https://reactjs.org/docs/hooks-reference.html#usememo

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM