1. ホーム
  2. ジャバスクリプト

[解決済み】ReactのuseEffectフックを初期レンダリング時に実行しないようにする

2022-04-10 13:56:17

質問

ドキュメントによると

componentDidUpdate() は、更新が発生した直後に呼び出されます。このメソッドは、最初のレンダリングでは呼び出されません。

新しい useEffect() をシミュレートするためのフックです。 componentDidUpdate() のようですが、どうやら useEffect() は、初回であっても、レンダリングのたびに実行されます。どうすれば、初回レンダリング時に実行されないようにできますか?

下の例でわかるように componentDidUpdateFunction は最初のレンダリング時に表示されますが componentDidUpdateClass は、最初のレンダリング時に印刷されませんでした。

function ComponentDidUpdateFunction() {
  const [count, setCount] = React.useState(0);
  React.useEffect(() => {
    console.log("componentDidUpdateFunction");
  });

  return (
    <div>
      <p>componentDidUpdateFunction: {count} times</p>
      <button
        onClick={() => {
          setCount(count + 1);
        }}
      >
        Click Me
      </button>
    </div>
  );
}

class ComponentDidUpdateClass extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }

  componentDidUpdate() {
    console.log("componentDidUpdateClass");
  }

  render() {
    return (
      <div>
        <p>componentDidUpdateClass: {this.state.count} times</p>
        <button
          onClick={() => {
            this.setState({ count: this.state.count + 1 });
          }}
        >
          Click Me
        </button>
      </div>
    );
  }
}

ReactDOM.render(
  <div>
    <ComponentDidUpdateFunction />
    <ComponentDidUpdateClass />
  </div>,
  document.querySelector("#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>

解決方法は?

を使用することができます。 useRef フックを使って、任意のミュータブルな値を保存することができます。 の最初の実行であるかどうかを記録するために使用できます。 useEffect 関数が実行されています。

と同じフェーズで効果を実行させたい場合。 componentDidUpdate を使用することができます。 useLayoutEffect の代わりに

const { useState, useRef, useLayoutEffect } = React;

function ComponentDidUpdateFunction() {
  const [count, setCount] = useState(0);

  const firstUpdate = useRef(true);
  useLayoutEffect(() => {
    if (firstUpdate.current) {
      firstUpdate.current = false;
      return;
    }

    console.log("componentDidUpdateFunction");
  });

  return (
    <div>
      <p>componentDidUpdateFunction: {count} times</p>
      <button
        onClick={() => {
          setCount(count + 1);
        }}
      >
        Click Me
      </button>
    </div>
  );
}

ReactDOM.render(
  <ComponentDidUpdateFunction />,
  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>