Заставить React useEffect не запускаться при начальном рендере - PullRequest
0 голосов
/ 12 ноября 2018

По документам:

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/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>

<div id="app"></div>

1 Ответ

0 голосов
/ 12 ноября 2018

Мы можем использовать хук 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/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>

<div id="app"></div>
...