我一直在分别使用React和D3,现在有一个项目需要对应用程序的绘图功能进行低级控制。基本上,我需要能够在用户放大图时从数据库中获取更高分辨率的数据,反之亦然随着用户缩小图而从数据库中获取更高分辨率的数据。
我发现了几种同时使用D3和React的方法。我想尝试使我的所有React代码都基于hooks API,因为这是其余代码库所使用的。我正在努力使自己面对的特定情况变得与众不同。关于React钩子的文档很棒,但是我认为我的情况更多是边缘情况,而且我还没有看到与类似用例有关的讨论。
代码的逻辑非常简单: 我有一个主容器,称为App.js,它具有某种状态。 App.js呈现一个Wrapper组件(正在发生挑战),然后Wrapper.js文件仅创建D3绘图。 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;
我已经开始将下面的hooks版本放在一起,但是我无法提出合适的方法来满足我对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组件。
这是完全可能的还是我最好还是将其作为基于类的组件?
我一直在撞墙,试图获得没有成功的逻辑,因此将不胜感激。
答案 0 :(得分:0)
您可以使用适当的依赖关系将返回值包装在React useMemo中。