Я проверил это и то из React basics с помощью `console.log()`.

Нажмите здесь, чтобы прочитать статью на японском языке:https://zenn.dev/takuyakikuchi/articles/2c4071a58bd4d7

console.log() для проверки времени рендеринга

⚠️ Для упрощения протоколирования результатов, «Строгий режим» намеренно отключен, чтобы жизненный цикл никогда не вызывался дважды.

Строгий режим — React

1. Обновление состояния в родительском и дочернем компоненте и повторный рендеринг

Что нужно подтвердить

  • Проверьте повторный рендеринг при изменении состояния в родительском и дочернем компонентах.

Код

  • Родительский компонент: App
  • Дочерний компонент: count.
    • Имеет состояние count.
const ChildA = ({ state }) => {
  const [count, setCount] = React.useState(0);
+ console.log(`rendering in child A component: count has ${count}`);
  return (
    ...
      <button onClick={() => setCount(count + 1)}>Child A: Count-up</button>
    ...
  );
};
const ChildB = () => {
  console.log("rendering in child B component");
  return <div>Child B doesn't have props passed from the parent</div>;
};
export default function App() {
  const [state, setState] = React.useState(false);
  console.log("rendering in parent component");
  return (
    <div className="App">
      ...
      <button onClick={() => setState(!state)}>Update the parent state</button>
      ...
      <ChildA state={state} />
      ...
      <ChildB />
    </div>
  );
}
Вход в полноэкранный режим Выход из полноэкранного режима

Результаты консоли

<!-- 1. Initial rendering -->
rendering in parent component 
rendering in child A component: count has 0 
rendering in child B component 
<!-- 2. Update the parent state -->
rendering in parent component 
rendering in child A component: count has 0 
rendering in child B component 
<!-- 3. Update the child A state -->
rendering in child A component: count has 1 
<!-- 4. Update the parent state -->
rendering in parent component 
rendering in child A component: count has 1 
rendering in child B component 
Вход в полноэкранный режим Выход из полноэкранного режима

Подтверждено

  • При изменении состояния родительского компонента перерисовка происходит как в родительском, так и в дочерних компонентах, независимо от того, передаются реквизиты или нет. (См. № 2)
  • Когда состояние изменяется в дочернем компоненте, перерисовка происходит только в этом компоненте. (См. № 3)
  • Когда родительский компонент перерендеривается, а дочерний компонент перерендеривается, состояние дочернего компонента поддерживается в актуальном состоянии. (См. № 4)

Демонстрация

2. useState initialState против ленивого начального состояния

Что нужно подтвердить

  • Подтвердите, что ленивое начальное состояние вызывается только при начальном рендеринге.
  • С другой стороны, подтвердите, что initialState вызывается при каждом повторном рендеринге.

React: useState

Код

  • Родительский компонент: App
  • Дочерний компонент: Child.
const someExpensiveCalculation = (number, type) => {
  console.log(`in the ${type} initial state`);
  return number * 10;
};
const Child = ({ number }) => {
  const [childStateA, setChildStateA] = React.useState(() => {
    return someExpensiveCalculation(number, "lazy");
  });
  const [childStateB, setChildStateB] = React.useState(
    someExpensiveCalculation(number, "default")
  );
  console.log(
    `rendering in child component: A: ${childStateA}, B: ${childStateB}`
  );
  return (
    <>
      <p>{`The childStateA is ${childStateA}`}</p>
      <button onClick={() => setChildStateA(childStateA + 1)}>
        Child A: Count-up
      </button>
      <p>{`The childStateB is ${childStateB}`}</p>
      <button onClick={() => setChildStateB(childStateB + 1)}>
        Child B: Count-up
      </button>
    </>
  );
};
export default function App() {
  const [state, setState] = React.useState(false);
  return (
    <div className="App">
      <button onClick={() => setState(!state)}>Update the parent state</button>
      <Child number={10} />
    </div>
  );
}
Вход в полноэкранный режим Выход из полноэкранного режима

Результат консоли

<!-- 1. Initial rendering -->
in the lazy initial state 
in the default initial state 
rendering in child component: A: 100, B: 100 
<!-- 2. Parent state update -->
in the default initial state 
rendering in child component: A: 100, B: 100 
<!-- 3. Child state A update -->
in the default initial state 
rendering in child component: A: 101, B: 100 
<!-- 3. Child state B update -->
in the default initial state 
rendering in child component: A: 101, B: 101 
<!-- 4. Parent state update -->
in the default initial state 
rendering in child component: A: 101, B: 101 
Вход в полноэкранный режим Выход из полноэкранного режима

Подтверждено

  • При ленивом начальном состоянии, someExpensiveCalculation()` вызывается только при начальном рендеринге, и игнорируется при повторном рендеринге.
  • С другой стороны, когда значение передается просто как initialState, someExpensiveCalculation()` вызывается каждый раз при повторном рендеринге.

Демонстрация

3. Время выполнения useEffect

Вещи, которые необходимо подтвердить

  • Убедитесь, что функция, переданная в useEffect, запускается после того, как результат рендеринга отражается на экране.

React: useEffect

Код

  • В useEffect, где state является зависимым значением, обновите состояние message после получения данных.
const dataFetchMock = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("setMessage executed in useEffect");
  }, 1500);
});
export default function App() {
  const [message, setMessage] = React.useState();
  const [state, setState] = React.useState(false);
  React.useEffect(() => {
    console.log(`in useEffect. state: ${state}`);
    dataFetchMock.then((value) => {
      setMessage(value);
    });
  }, [state]);

  console.log(`rendering: just before return jsx. message: ${message}`);
  return (
    <div className="App">
      <button onClick={() => setState(!state)}>Update the parent state</button>
      <p>{message === undefined ? "undefined" : message}</p>
    </div>
  );
}
Вход в полноэкранный режим Выход из полноэкранного режима

Результат работы консоли

<!-- 1. Initial rendering -->
rendering: just before return jsx. message: undefined 
in useEffect. state: false 
rendering: just before return jsx. message: setMessage executed in useEffect 
<!-- 2. State(dependency of the useEffect) updated -->
rendering: just before return jsx. message: setMessage executed in useEffect 
in useEffect. state: true 
rendering: just before return jsx. message: setMessage executed in useEffect 
Вход в полноэкранный режим Выход из полноэкранного режима

Подтверждено

  • * UseEffect работает после рендеринга. *
    • Первоначальный рендеринг (см. №1), сначала рендеринг => useEffect => изменение состояния message в useEffect вызвало повторный рендеринг.
    • При обновлении состояния, содержащегося в массиве зависимостей useEffect (см. №2), рендеринг путем обновления состояния => useEffect => повторный рендеринг путем изменения состояния message в useEffect.

Демонстрация

Резюме

React можно использовать со смутным пониманием.
Однако я подумал, что было бы полезно самостоятельно проверить время повторного рендеринга и т.д.

Оцените статью
devanswers.ru
Добавить комментарий