新しく提案された React Effect Hook ;について
Effect
フック(useEffect()
)の利点と使用例は何ですか?
なぜそれが望ましいのでしょうか、それがcomponentDidMount/componentDidUpdate/componentWillUnmount
(パフォーマンス/読みやすさ)とどう違うのですか?
ドキュメントには、次のように記載されています。
ミューテーション、サブスクリプション、タイマー、ロギング、およびその他の副作用は、関数コンポーネントのメインボディ内では許可されていません(Reactのレンダリングフェーズと呼ばれます)。
しかし、renderメソッドの代わりに、componentDidUpdateなどのライフサイクルメソッドでこれらの動作を行うことは、すでに一般的な知識であったと思います。
また、次のような言及もあります。
レンダリングが画面にコミットされた後、useEffectに渡された関数が実行されます。
とにかくcomponentDidMount
とcomponentDidUpdate
は何をしているのではないですか?
Effect
フック(useEffect()
)の利点と使用例は何ですか?
主に、フックは一般に、より高次のコンポーネントやレンダリングプロップの負担なしに、複数のコンポーネントに共通するステートフルロジックの抽出と再利用を可能にします。
(特にエフェクトフックの)副次的な利点は、状態依存の副作用がcomponentDidUpdate
内で適切に処理されない場合に発生する可能性があるバグを回避できることです(エフェクトフックは、そのような副作用が確実にセットアップされ、引き裂かれるためすべてのレンダリングでダウン)。
以下に詳述するパフォーマンスと可読性の利点も参照してください。
ライフサイクルメソッドを使用してステートフルロジックを実装する任意のコンポーネント— Effectフックは「より良い方法」です。
なぜそれが望ましいのでしょうか、そして
componentDidMount
/componentDidUpdate
/componentWillUnmount
(パフォーマンス/読みやすさ)とどう違うのですか?
上記および下記に詳述する利点があるため。
エフェクトフック—
エフェクトフックの結果:
以前は同じライフサイクルメソッドのセット全体で表現する必要があった無関係の動作を、そのような動作ごとに1つのフックに分割できるため、よりシンプルで保守しやすいコンポーネント。たとえば、次のようになります。
componentDidMount() {
prepareBehaviourOne();
prepareBehaviourTwo();
}
componentDidUnmount() {
releaseBehaviourOne();
releaseBehaviourTwo();
}
になる:
useEffect(() => {
prepareBehaviourOne();
return releaseBehaviourOne;
});
useEffect(() => {
prepareBehaviourTwo();
return releaseBehaviourTwo;
});
BehaviourOne
に関連するコードがBehaviourTwo
に関連するコードから明確に分離されていることに注意してください。以前は、各ライフサイクルメソッド内に混在していました。
複数のライフサイクルメソッド(componentDidMount
とcomponentDidUpdate
の間で共通など)全体で同じコードを繰り返す必要がなくなるため、ボイラープレートが少なくなります。次に例を示します。
componentDidMount() {
doStuff();
}
componentDidUpdate() {
doStuff();
}
になる:
useEffect(doStuff); // you'll probably use an arrow function in reality
これはReactConf2018Dan Abramovのトークの違いを説明する例です。
以下は、以下の例からのいくつかの調査結果です。
useEffect()
を使用したライフサイクル更新および状態更新へのアクセスComponentDidMountやcomponentDidUpdateとは異なり、useEffectに渡された関数は、レイアウトとペイントの後で、遅延イベントの間に起動します
useEffect()
フックに2番目の引数として渡すことで、コンポーネントの再レンダリングをより効率的に制御できます。これは、空の配列[]を渡すだけでコンポーネントのマウントとアンマウントでのみレンダリングする場合に非常に効果的です。useEffect()
フックを使用して懸念を分離し、以下のように反応します。フックを使用すると、ライフサイクルメソッド名ではなく、実行内容に基づいてコードを分割できます。 Reactは、コンポーネントが使用するすべてのエフェクトを、指定された順序で適用します
クラスの使用:
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
componentDidMount() {
document.title = `You clicked ${this.state.count} times`;
}
componentDidUpdate() {
document.title = `You clicked ${this.state.count} times`;
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}
フックの使用:
import { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
// Update the document title using the browser API
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}