我有一个父组件,它的状态变量在交互时被它的一个子组件改变。然后,父组件还根据状态变量中的数据包含一些更多的组件。
问题是,当其父组件的状态发生变化时,因为对setState函数的引用发生了变化,子组件才会呈现。但是当我使用useCallback(如这里所建议的)时,我的父节点的状态根本不更新。
这是我当前的设置:
function ArtistGraphContainer() {
const [artistPopUps, setArtistPopUps] = useState([])
const addArtistPopUp = useCallback(
(artistGeniusId, xPos, yPos) => {
setArtistPopUps([{artistGeniusId, xPos, yPos}].concat(artistPopUps))
},
[],
)
return (
<div className='artist-graph-container'>
<ArtistGraph addArtistPopUp={addArtistPopUp} key={1}></ArtistGraph>
{artistPopUps.map((popUp) => {
<ArtistPopUp
artistGeniusId={popUp.artistGeniusId}
xPos={popUp.xPos}
yPos={popUp.yPos}
></ArtistPopUp>
})}
</div>
)
}
和子组件:
function ArtistGraph({addArtistPopUp}) {
// querying data
if(records) {
// wrangling data
const events = {
doubleClick: function(event) {
handleNodeClick(event)
}
}
return (
<div className='artist-graph'>
<Graph
graph={graph}
options={options}
events={events}
key={uniqueId()}
>
</Graph>
</div>
)
}
else{
return(<CircularProgress></CircularProgress>)
}
}
function areEqual(prevProps, nextProps) {
return true
}
export default React.memo(ArtistGraph, areEqual)
在任何其他情况下,子组件的重新呈现都不会是这样的问题,但遗憾的是它会导致图形重绘。
那么我如何管理更新父组件的状态而不重新绘制图形?
提前感谢!
有几件事,孩子可能会重新呈现,但这不是你所说的原因。setState
函数的身份是有保证的,它们不会因为渲染而改变。这就是为什么将它们从useEffect
,useMemo
和useCallback
中的依赖数组中排除是安全的。如果您想进一步了解这一点,可以查看我设置的沙盒:https://codesandbox.io/s/funny-carson-sip5x
在我的示例中,您将看到,当您单击子组件的按钮时,父组件的状态发生了变化,但是如果子组件正在重新呈现,则会触发的控制台日志没有记录。
鉴于上述情况,我将远离您现在使用的usCallback
方法。我得说这是反模式的。作为一个警告,你的useCallback缺少一个必需的依赖项,artistPopUp
。
从那里很难说是什么原因导致你的组件渲染,因为你的例子缺少关键信息,比如graphs
,options
,或records
值来自哪里。可能导致意外呈现的一件事是,如果您在某些时候导致父组件或子组件的完全安装和卸载。
最后注意,您绝对不需要将第二个参数传递给React.memo
。