web-dev-qa-db-ja.com

React useEffectで一度だけロード関数を呼び出す方法

useEffect Reactフックは、変更があるたびに渡された関数を実行します。これは、目的のプロパティが変更されたときにだけ呼び出すように最適化できます。

componentDidMountから初期化関数を呼び出して、変更時に再度呼び出さないようにしたい場合はどうすればいいですか?エンティティをロードしたいのですが、ロード機能はコンポーネントからのデータを必要としません。 useEffectフックを使用してこれをどのように作成できますか?

class MyComponent extends React.PureComponent {
    componentDidMount() {
        loadDataOnlyOnce();
    }
    render() { ... }
}

フックの場合、これは次のようになります。

function MyComponent() {
    useEffect(() => {
        loadDataOnlyOnce(); // this will fire on every change :(
    }, [...???]);
    return (...);
}
59
Dávid Molnár

最初のレンダリングの後にuseEffectに与えられた関数だけを実行したい場合は、2番目の引数として空の配列を指定できます。

function MyComponent() {
  useEffect(() => {
    loadDataOnlyOnce();
  }, []);

  return <div> {/* ... */} </div>;
}
117
Tholle

空の配列を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>
10
Yangshun Tay

TL; DR

useEffect(yourCallback, []) - 最初のレンダリングの後にだけコールバックを引き起こします。

詳しい説明

useEffectは、デフォルトでは - - コンポーネントのレンダリング後に実行されます(したがって効果が発生します)。

あなたのコンポーネントにuseEffectを入れるとき、あなたはReactにコールバックを効果的に実行したいと伝えます。レンダリング後およびDOMの更新後に、Reactはエフェクトを実行します。

コールバックのみを渡すと、コールバックは各レンダリングの後に実行されます。

2番目の引数(配列)を渡すと、Reactは最初のレンダリングの後、配列の要素の1つが変更されるたびにコールバックを実行します。例えばuseEffect(() => console.log('hello'), [someVar, someOtherVar])を配置するとき - コールバックは最初のレンダリングの後とsomeVarまたはsomeOtherVarのいずれかが変更されたレンダリングの後に実行されます。

2番目の引数に空の配列を渡すことで、Reactは各レンダリング後に配列を比較し、何も変更されていないことを確認します。したがって、最初のレンダリング後にのみコールバックを呼び出します。

10
Edan Chetrit

useMountEffectフック

コンポーネントのマウント後に関数を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は、マウント(初期レンダリング)後および配列の値が変更された後にコールバックを実行します。空の配列を渡すため、マウント後にのみ実行されます。

8
Ben Carp