我刚刚开始尝试使用React钩子,我想知道如何防止子组件在父级重新渲染时重新渲染.我正在寻找类似于在componentDidUpdate中返回false的东西.我的问题似乎源于我在子组件中调用的click处理程
function Parent() { const [item, setItem] = useState({ name: "item", value: 0 }); const handleChangeItem = () => { const newValue = item.value + 1; setItem({ ...item, value: newValue }); }; return <Child item={item} changeItem={handleChangeItem} />; } const Child = React.memo(function Child({ item, changeItem }) { function handleClick(){ changeItem(); } return ( <div> Name: {item.name} Value: {item.value} <button onClick={handleClick}>change state in parent</button> </div> ); });
如何在每次父组件渲染时阻止子组件渲染?父进程中的handleChangeItem应该位于其他地方,以便不在每次渲染时重新创建吗?如果是这样,它如何访问useState返回的item和setItem?
我很快就会做出反应并开始玩钩子所以我可能会错过一些明显的东西.
在你的情况下,记住Child是没有意义的,因为如果项目发生变化,孩子必须重新渲染.但是,如果有一个道具不会改变的情况,但是由于重新创建的函数,孩子仍在重新渲染,你将使用useCallback
钩子来记忆每个渲染上的函数.此外,由于您已经记住了处理程序,因此您应该使用回调方法来更新状态,因为处理程序中的项目只会引用最初创建函数时的值.
function Parent() { const [item, setItem] = useState({ name: "item", value: 0 }); const handleChangeItem = useCallback(() => { setItem(prevItem => ({ ...prevItem, value: prevItem.value + 1 })); }, []); return ( <> Name: {item.name} Value: {item.value} <Child changeItem={handleChangeItem} /> </> ); } const Child = React.memo(function Child({ item, changeItem }) { function handleClick() { changeItem(); } console.log("child render"); return ( <div> <button onClick={handleClick}>change state in parent</button> </div> ); });
Working demo
附: Credit to @danAbramov for the direction