useEffect Reactフックは、変更があるたびに渡された関数を実行します。これは、目的のプロパティが変更されたときにだけ呼び出すように最適化できます。
componentDidMount
から初期化関数を呼び出して、変更時に再度呼び出さないようにしたい場合はどうすればいいですか?エンティティをロードしたいのですが、ロード機能はコンポーネントからのデータを必要としません。 useEffect
フックを使用してこれをどのように作成できますか?
class MyComponent extends React.PureComponent {
componentDidMount() {
loadDataOnlyOnce();
}
render() { ... }
}
フックの場合、これは次のようになります。
function MyComponent() {
useEffect(() => {
loadDataOnlyOnce(); // this will fire on every change :(
}, [...???]);
return (...);
}
最初のレンダリングの後にuseEffect
に与えられた関数だけを実行したい場合は、2番目の引数として空の配列を指定できます。
function MyComponent() {
useEffect(() => {
loadDataOnlyOnce();
}, []);
return <div> {/* ... */} </div>;
}
空の配列をuseEffect
の2番目の引数として渡します。これは事実上Reactにドキュメントを引用しながら伝えます:
これはReactにあなたの効果は小道具や状態からの値には依存しないことを伝えているので、再実行する必要は決してない。
これが動作することを示すために実行できるスニペットです。
function App() {
const [user, setUser] = React.useState(null);
React.useEffect(() => {
fetch('https://randomuser.me/api/')
.then(results => results.json())
.then(data => {
setUser(data.results[0]);
});
}, []); // Pass empty array to only run once on mount.
return <div>
{user ? user.name.first : 'Loading...'}
</div>;
}
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<div id="app"></div>
TL; DR
useEffect(yourCallback, [])
- 最初のレンダリングの後にだけコールバックを引き起こします。
詳しい説明
useEffect
は、デフォルトでは - - コンポーネントのレンダリング後に実行されます(したがって効果が発生します)。
あなたのコンポーネントにuseEffect
を入れるとき、あなたはReactにコールバックを効果的に実行したいと伝えます。レンダリング後およびDOMの更新後に、Reactはエフェクトを実行します。
コールバックのみを渡すと、コールバックは各レンダリングの後に実行されます。
2番目の引数(配列)を渡すと、Reactは最初のレンダリングの後、配列の要素の1つが変更されるたびにコールバックを実行します。例えばuseEffect(() => console.log('hello'), [someVar, someOtherVar])
を配置するとき - コールバックは最初のレンダリングの後とsomeVar
またはsomeOtherVar
のいずれかが変更されたレンダリングの後に実行されます。
2番目の引数に空の配列を渡すことで、Reactは各レンダリング後に配列を比較し、何も変更されていないことを確認します。したがって、最初のレンダリング後にのみコールバックを呼び出します。
コンポーネントのマウント後に関数を1回だけ実行することは、実装の詳細を隠す独自のフックを正当化するような一般的なパターンです。
const useMountEffect = (fun) => useEffect(fun, [])
機能コンポーネントで使用します。
function MyComponent() {
useMountEffect(function) // function will run only once after it has mounted.
return <div>...</div>;
}
seMountEffectフックについて
useEffect
を2番目の配列引数と共に使用する場合、Reactは、マウント(初期レンダリング)後および配列の値が変更された後にコールバックを実行します。空の配列を渡すため、マウント後にのみ実行されます。