主要组件正在调用模态/对话框。
[...]
const closeDialog = () => setIsOpenDialog(false);
return (
<MyDialog
isOpen={isOpenDialog}
onClose={closeDialog}
/>
);
MyDialog 代码是:
[...]
useEffect(() => {
console.log('This removes dialog states (data)!')
}, [onClose]);
export default function MyDialog({
isOpen,
onClose,
}) {
return (
<Dialog
isOpen={isOpen}
onClose={onClose}
dialogTitle="Add/Edit"
onClickCancel={onClose}
>
[...]
</Dialog>
);
}
当我点击 Cancel 并调用 onClose 时,我可以看到 useEffect 已触发。请问这是什么原因呢?我的理解是不应该,因为 onClose 函数对象(来自 props)不会改变。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
当依赖数组中的任何依赖项发生更改时,React 中的
useEffect挂钩就会运行。在您的情况下,useEffect依赖于onClose属性。因此,每次onClose属性更改时都会运行。但是,即使代码中的
onClose函数未发生更改,由于 JavaScript 处理函数标识的方式,useEffect可能仍会运行。在 JavaScript 中,每次定义函数时,它都是一个新实例,即使它执行完全相同的操作。因此,就您而言,每次组件重新渲染时,您都将
closeDialog定义为渲染函数中的新函数。这意味着,从 React 的角度来看,onClose每次都是一个新函数,它会触发useEffect。要解决此问题,您可以使用
useCallback挂钩来确保您的closeDialog函数在渲染之间具有稳定的标识,除非其依赖项发生变化:在上面的示例中,
useCallback返回函数的记忆版本,该版本仅在依赖项之一发生更改时才会更改。在这种情况下,依赖项数组为空 ([]),这意味着closeDialog函数的标识在重新渲染时将保持稳定。