簡體   English   中英

了解 React Hooks 'exhaustive-deps' lint 規則

[英]Understanding the React Hooks 'exhaustive-deps' lint rule

我很難理解 'exhaustive-deps' lint 規則。

我已經閱讀了這篇文章這篇文章,但我找不到答案。

這是一個帶有 lint 問題的簡單 React 組件:

const MyCustomComponent = ({onChange}) => {
    const [value, setValue] = useState('');

    useEffect(() => {
        onChange(value);
    }, [value]);

    return (
        <input 
           value={value} 
           type='text' 
           onChange={(event) => setValue(event.target.value)}>
        </input>
    )
} 

它要求我將onChange添加到useEffect依賴項數組。 但在我的理解onChange永遠不會改變,所以它不應該在那里。

通常我是這樣管理的:

const MyCustomComponent = ({onChange}) => {
    const [value, setValue] = useState('');

    const handleChange = (event) => {
        setValue(event.target.value);
        onChange(event.target.value)
    }

    return (
        <input 
           value={value} 
           type='text'
           onChange={handleChange}>
        </input> ​
    )
} 

為什么是棉絨? 關於第一個示例的 lint 規則有什么明確的解釋嗎?

或者我不應該在這里使用useEffect嗎? (我是一個有鈎子的菜鳥)

linter 規則希望onChange到 go 進入useEffect掛鈎的原因是onChange可以在渲染之間更改,並且 lint 規則旨在防止這種“陳舊數據”引用。

例如:

const MyParentComponent = () => {
    const onChange = (value) => { console.log(value); }

    return <MyCustomComponent onChange={onChange} />
}

MyParentComponent的每個渲染都會將不同的onChange function 傳遞給MyCustomComponent

在您的特定情況下,您可能不在乎:您只想在值更改時調用onChange ,而不是在onChange function 更改時調用。 但是,從您如何使用useEffect ,這並不清楚。


這里的根源是您的useEffect有點單調。

useEffect最適合用於副作用,但在這里您將其用作一種“訂閱”概念,例如:“當 Y 變化時執行 X”。 由於deps數組的機制,這確實在功能上起作用(盡管在這種情況下,您還在初始渲染時調用onChange ,這可能是不需要的),但這不是預期的目的。

在這里調用onChange真的不是副作用,它只是觸發<input>onChange事件的效果。 因此,我確實認為您同時調用onChangesetValue的第二個版本更慣用。

如果有其他設置值的方法(例如清除按鈕),經常需要記住調用onChange可能會很乏味,所以我可以這樣寫:

const MyCustomComponent = ({onChange}) => {
    const [value, _setValue] = useState('');

    // Always call onChange when we set the new value
    const setValue = (newVal) => {
        onChange(newVal);
        _setValue(newVal);
    }

    return (
        <input value={value} type='text' onChange={e => setValue(e.target.value)}></input>
        <button onClick={() => setValue("")}>Clear</button>
    )
}

但在這一點上,這是令人毛骨悚然的。

exhaustive-deps警告的主要目的是防止開發人員在其效果中丟失依賴項並丟失某些行為。

Dan abramov – Facebook 內核的開發人員 – 強烈建議啟用該規則

對於將函數作為依賴項傳遞的情況, React FAQ 中有專門的章節

https://reactjs.org/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies

tl;博士

如果您必須將 function 放入您的依賴項數組中:

  • 將 function 放在組件之外,這樣您就可以確定每次渲染時不會更改引用。
  • 如果可以,請在效果之外調用 function,並將結果用作依賴項。
  • 如果 function 必須在您的組件 scope 中聲明,您必須使用useCallback鈎子記住 function 引用。 僅當回調 function 的依賴項發生更改時,才會更改引用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM