Как происходит обновление компонента в React?

Как работает функция обновления в React, которая используется как аргумент в установщике состояния? В чем разница между setCount(count + 1) и setCount(prevCount => prevCount + 1) в данном примере кода:

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

  const increment = () => {
    setCount(prevCount => prevCount + 1);
  };

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

Интересует, как происходит изменение значения count при каждом клике на кнопку, начиная с первичного рендера компонента. Нужно понять, какие шаги происходят с состоянием компонента от рендера к рендеру.
  • 25 сентября 2023 г. 6:38
Ответы на вопрос 2
В React обновление компонента происходит следующим образом:

1. При первичном рендеринге компонента, функция Counter() вызывается и возвращает JSX-элемент. На этом этапе значение count равно 0.

2. React создает виртуальное представление DOM (Virtual DOM), которое представляет текущее состояние компонента.

3. Виртуальное представление DOM сравнивается с предыдущим состоянием DOM и определяются изменения, которые необходимо внести.

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

5. Компонентный элемент в DOM обновляется с использованием изменений, выявленных на предыдущем шаге.

Теперь давайте посмотрим на обновление состояния в функции increment():

- Вызывается функция обновления setCount() с аргументом - новым значением состояния. В данном случае, это prevCount => prevCount + 1.

- setCount(prevCount => prevCount + 1) обновляет состояние, увеличивая значение prevCount на 1 и затем устанавливает новое значение count.

Если использовать setCount(count + 1), то результат будет другим:

- setCount(count + 1) получает текущее значение count, добавляет к нему 1 и устанавливает новое значение count. Однако, в данном случае, это небезопасно, так как состояние обновляется асинхронно и при использовании этого подхода вы можете получить некорректное значение count.

Вариант prevCount => prevCount + 1 предоставляет функциональный аргумент, который гарантирует, что вы получите последнее актуальное значение состояния, вне зависимости от того, когда обновление происходит.

Итак, через функцию обновления в setState() вы можете обновлять состояние, основываясь на предыдущем значении, что рекомендуется при работе с настоящим состоянием.
Вот переформулированный код функции useState:

```javascript
function useState(initialValue) {
  component.useStateCount++; // увеличиваем счетчик вызовов useState в компоненте

  if (component.useStateCount in component.useStateCache) {
    return component.useStateCache[component.useStateCount]; // возвращаем результат из кэша, если уже был вызов этого useState
  }
  
  const useStateResult = [
    initialValue, 
    function setState(callbackOrValue) {
      if (typeof callbackOrValue === 'function') {
        useStateResult[0] = callbackOrValue(useStateResult[0]); // вызываем функцию с предыдущим значением в качестве аргумента и присваиваем результат вызова в state
      } else {
        useStateResult[0] = callbackOrValue; // просто присваиваем аргумент в state
      }

      component.updateComounent(); // вызываем обновление компонента
    }
  ];

  component.useStateCache[component.useStateCount] = useStateResult; // добавляем в кэш

  return useStateResult; // возвращаем результат
}
```

Стало понятнее?
Похожие вопросы