為什麼當我使用 props 中的函數時會觸發 useEffect (函數沒有改變)?
P粉662802882
P粉662802882 2023-09-12 22:40:30
0
1
448

主要元件正在呼叫模態/對話框。

[...]
  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)不會改變。

P粉662802882
P粉662802882

全部回覆(1)
P粉165823783

當依賴數組中的任何相依性發生變更時,React 中的 useEffect 掛鉤就會運作。在您的情況下,useEffect 依賴onClose 屬性。因此,每次 onClose 屬性變更時都會執行。

但是,即使程式碼中的 onClose 函數未發生更改,由於 JavaScript 處理函數標識的方式,useEffect 可能仍會運行。在 JavaScript 中,每次定義函數時,它都是一個新實例,即使它執行完全相同的操作。

因此,就您而言,每次元件重新渲染時,您都會將 closeDialog 定義為渲染函數中的新函數。這意味著,從 React 的角度來看,onClose 每次都是新函數,它會觸發 useEffect

要解決此問題,您可以使用 useCallback 掛鉤來確保您的 closeDialog 函數在渲染之間具有穩定的標識,除非其依賴項變更:

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

在上面的範例中,useCallback 傳回函數的記憶版本,該版本僅在依賴項之一發生變更時才會變更。在這種情況下,依賴項數組為空 ([]),這表示 closeDialog 函數的標識在重新渲染時將保持穩定。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板