Maison  >  Questions et réponses  >  le corps du texte

Pourquoi useEffect se déclenche-t-il lorsque j'utilise une fonction à partir d'accessoires (la fonction n'a pas changé) ?

Le composant principal appelle le modal/dialog.

[...]
  const closeDialog = () => setIsOpenDialog(false);
  return (
      <MyDialog
        isOpen={isOpenDialog}
        onClose={closeDialog}
      />
  );

Mon code de dialogue est :

[...]
  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>
);
}

Quand je clique sur Annuler et appelle onClose 时,我可以看到 useEffect触发。请问这是什么原因呢?我的理解是不应该,因为 onClose 函数对象(来自 props), rien ne change.

P粉662802882P粉662802882425 Il y a quelques jours438

répondre à tous(1)je répondrai

  • P粉165823783

    P粉1658237832023-09-13 11:52:56

    useEffect 挂钩就会运行。在您的情况下,useEffect 依赖于onClose 属性。因此,每次 onClose Les propriétés de React sont exécutées lorsqu'une dépendance du tableau de dépendances change.

    Cependant, même le onClose 函数未发生更改,由于 JavaScript 处理函数标识的方式,useEffect dans le code peut toujours s'exécuter. En JavaScript, chaque fois que vous définissez une fonction, c'est une nouvelle instance, même si elle fait exactement la même chose.

    Donc, dans votre cas, chaque fois que le composant sera restitué, vous le ferez closeDialog 定义为渲染函数中的新函数。这意味着,从 React 的角度来看,onClose 每次都是一个新函数,它会触发 useEffect.

    Pour résoudre ce problème, vous pouvez utiliser la fonction useCallback 挂钩来确保您的 closeDialog pour avoir une identité stable entre les rendus à moins que ses dépendances ne changent :

    const closeDialog = React.useCallback(() => setIsOpenDialog(false), []);

    Dans l'exemple ci-dessus, l'identité de la fonction useCallback 返回函数的记忆版本,该版本仅在依赖项之一发生更改时才会更改。在这种情况下,依赖项数组为空 ([]),这意味着 closeDialog restera stable lors des nouveaux rendus.

    répondre
    0
  • Annulerrépondre