【问题标题】:React setState of Parent component without rerendering the Child在不重新渲染子组件的情况下反应父组件的 setState
【发布时间】:2021-09-14 04:00:26
【问题描述】:

我有一个带有状态变量的父组件,该状态变量在交互时被其子组件之一更改。然后父级还包含一些基于状态变量中的数据的更多组件。

问题是子组件在其父组件的状态发生更改时重新渲染,因为对 setState 函数的引用发生了更改。但是当我使用 useCallback(建议 here)时,我父母的状态根本不会更新。

这是我目前的设置:

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)

在任何其他情况下,子组件的重新渲染都不会是这样的问题,但遗憾的是它会导致图形重绘。

那么如何在不重绘图表的情况下更新父组件的状态?

提前致谢!

【问题讨论】:

    标签: javascript reactjs react-hooks


    【解决方案1】:

    有几件事,孩子可能会重新渲染,但这不是您所说的原因。 setState 函数的身份得到保证,它们不会因为重新渲染而改变。这就是为什么可以安全地将它们从 useEffectuseMemouseCallback 中的依赖数组中排除。如果您想进一步证明这一点,可以查看我设置的这个沙箱:https://codesandbox.io/s/funny-carson-sip5x

    在我的示例中,当您单击子级按钮时,您会看到父组件状态发生了变化,但是如果子级重新渲染将触发的控制台日志没有记录。

    鉴于上述情况,我会放弃您现在使用的 usCallback 方法。我会说这是反模式。不过作为警告,您的 useCallback 缺少必需的依赖项artistPopUp

    从那里很难说是什么导致您的组件重新呈现,因为您的示例缺少关键信息,例如 graphsoptionsrecords 值的来源。可能导致意外重新渲染的一件事是,如果您在某些时候导致父组件或子组件的完全装载和卸载。

    最后一点,您绝对不需要将第二个参数传递给React.memo

    【讨论】:

    • 感谢您的广泛回答!我想我必须更深入地研究获取数据的方式和 Graph 组件本身。
    猜你喜欢
    • 2020-08-18
    • 2017-04-03
    • 1970-01-01
    • 2018-09-19
    • 1970-01-01
    • 2018-08-12
    • 1970-01-01
    • 2019-06-01
    • 1970-01-01
    相关资源
    最近更新 更多