React Hooks の 'exhaustive-deps' lint ルールを理解する 質問する

React Hooks の 'exhaustive-deps' lint ルールを理解する 質問する

「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 なのでしょうか? 最初の例の lint ルールについて明確な説明はありますか?

それとも、ここでは使用しない方が良いのでしょうかuseEffect? (私はフックの初心者です)

ベストアンサー1

onChangeリンター ルールをフックに含める理由useEffectは、レンダリング間で変更される可能性がありonChange、リンター ルールはそのような「古いデータ」の参照を防ぐことを目的としているためです。

例えば:

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

    return <MyCustomComponent onChange={onChange} />
}

の各レンダリングでは、MyParentComponent異なるonChange関数が に渡されますMyCustomComponent

onChangeあなたの特定のケースでは、おそらく気にする必要はないでしょう。関数が変更されたときではなく、値が変更されたときにのみ呼び出したいのですonChange。しかし、 の使用方法からはそれが明らかではありませんuseEffect


ここでの根本は、your がuseEffectやや慣用表現でないということです。

useEffectは副作用に使用するのが最適ですが、ここでは「Y が変更されたら X を実行する」などの一種の「サブスクリプション」概念として使用しています。配列のメカニズムにより、機能的にはある程度機能しますがdeps(ただし、この場合はonChange初期レンダリングも呼び出しており、これはおそらく望ましくありません)、意図された目的ではありません。

を呼び出すことはonChange、実際にはここでの副作用ではなく、onChangeのイベントをトリガーする効果にすぎません。したがって、 との両方を一緒に呼び出す 2 番目のバージョンの方が慣用的だ<input>と思います。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>
    )
}

しかし、現時点ではこれは些細な問題です。

おすすめ記事