主要组件正在调用模态/对话框。
[...] 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
)不会改变。
当依赖数组中的任何依赖项发生更改时,React 中的
useEffect
挂钩就会运行。在您的情况下,useEffect
依赖于onClose
属性。因此,每次onClose
属性更改时都会运行。但是,即使代码中的
onClose
函数未发生更改,由于 JavaScript 处理函数标识的方式,useEffect
可能仍会运行。在 JavaScript 中,每次定义函数时,它都是一个新实例,即使它执行完全相同的操作。因此,就您而言,每次组件重新渲染时,您都将
closeDialog
定义为渲染函数中的新函数。这意味着,从 React 的角度来看,onClose
每次都是一个新函数,它会触发useEffect
。要解决此问题,您可以使用
useCallback
挂钩来确保您的closeDialog
函数在渲染之间具有稳定的标识,除非其依赖项发生变化:在上面的示例中,
useCallback
返回函数的记忆版本,该版本仅在依赖项之一发生更改时才会更改。在这种情况下,依赖项数组为空 ([]),这意味着closeDialog
函数的标识在重新渲染时将保持稳定。