他の状態に依存する状態があるとしましょう(たとえば、Aが変更されたときにBを変更したい場合)。
UseEffectフック内でAを監視し、Bを設定するフックを作成することは適切ですか?
ボタンをクリックすると、最初のエフェクトが起動し、bが変化し、次のレンダリングの前に2番目のエフェクトが起動するように、エフェクトはカスケードされますか?このようなコードを構造化することでパフォーマンスの低下はありますか?
let MyComponent = props => {
let [a, setA] = useState(1)
let [b, setB] = useState(2)
useEffect(
() => {
if (/*some stuff is true*/) {
setB(3)
}
},
[a],
)
useEffect(
() => {
// do some stuff
},
[b],
)
return (
<button
onClick={() => {
setA(5)
}}
>
click me
</button>
)
}
エフェクトは、1つのエフェクト内でsetStateを設定した場合でも、レンダリングフェーズの完了後に常に実行されます。別のエフェクトは、更新された状態を読み取り、レンダリングフェーズの後でのみアクションを実行します。
b
がchanging a
以外の理由で変更される可能性がある場合を除き、同じ効果で両方のアクションを実行することをお勧めしますが、その場合も同じロジックを実行したい
setState
内でuseEffect
を使用すると、おそらく発生させたくない無限ループが作成されます。
useEffect
は各レンダリングの後に呼び出され、setState
がその内部で使用されると、コンポーネントは再レンダリングされ、useEffect
などを呼び出します。
useState
内でuseEffect
を使用しても無限ループが発生しない唯一のケースは、useEffect(() => {....}, [])
のようなuseEffect
の2番目の引数として空の配列を渡す場合です。エフェクト関数は、最初のマウント/レンダリングの後でのみ一度呼び出す必要があります。
useEffectは、特定の小道具または状態をフックできます。そのため、無限ループフックを回避するために必要なことは、何らかの変数または状態をバインドすることです
例えば。
useEffect(myeffect, [])
上記の効果は、コンポーネントがレンダリングされた後にのみ発生します。これはcomponentDidMountライフサイクルに似ています
const [something, setSomething] = withState(0)
const [myState, setMyState] = withState(0)
useEffect(() => {
setSomething(0)
}, myState)
上記の効果は、私の状態が変更された場合にのみ発動します。これは、すべての変化する状態が発動するわけではないことを除き、componentDidUpdateと同様です。
これでさらに詳細を読むことができます link