use*_*640 12 reactjs react-hooks
我刚刚开始使用React钩子进行实验,我想知道如何在父组件重新渲染时阻止子组件重新渲染。我正在寻找类似于在中返回false的内容componentDidUpdate。我的问题似乎源于我在子组件中调用以更改父组件状态的单击处理程序。由于该函数是在父级组件中创建的,因此会在每个父级渲染上创建新函数,从而触发子级组件中的属性更改,然后导致子级重新渲染(我认为)。这是一些示例代码来帮助说明这种情况。
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>
);
});
Run Code Online (Sandbox Code Playgroud)
如何防止子组件在每次父组件渲染时都渲染?应该handleChangeItem在父级中住其他地方,以便不在每个渲染器上重新创建它吗?如果是这样,它如何访问item并setItem返回useState?
我是一个非常新的反应者,刚刚开始玩钩子游戏,所以我可能缺少明显的东西。
在您的情况下,记住Child确实没有意义,因为如果项发生更改,则必须重新渲染child。但是,如果情况是道具没有变化,但是由于重新创建了函数,仍然在重新渲染孩子,则您将useCallback在每个渲染器上使用钩子来记住函数。另外,由于已经记住了处理程序,因此应该使用回调方法来更新状态,因为item处理程序内部将仅引用其最初创建函数时所具有的值。
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>
);
});
Run Code Online (Sandbox Code Playgroud)
Shubham Khatri 准确地回答了原来的问题,但我添加这个答案是为了指出避免此回调问题的推荐方法。
来自文档:
当您有涉及多个子值的复杂状态逻辑时,useReducer 通常优于 useState。它还可以让您优化触发深度更新的组件的性能,因为您可以向下传递调度而不是回调。
来自常见问题解答:
在大型组件树中,我们建议的另一种选择是通过上下文从 useReducer 传递调度函数...
https://reactjs.org/docs/hooks-faq.html#how-to-avoid-passing-callbacks-down
所有这一切的关键是调度永远不会改变,这与每次渲染时创建的回调不同。
| 归档时间: |
|
| 查看次数: |
4001 次 |
| 最近记录: |