Тема
- #React
- #Virtual DOM
- #React useState
- #глубокое погружение
- #React Hooks
Создано: 2024-03-14
Создано: 2024-03-14 01:53
Странно, но в React-сообществе очень любят использовать префикс `use`
useServer, useCallback, useState, useMemo и т.д.
Даже кастомные хуки используют `use`
Откуда это взялось?
useState — известный хук.
Он хранит состояние и перерисовывает компонент при его изменении. Очень просто.
Это всем известный пример.
Только тега `<p>`? Или же и `<button>`?
Правильный ответ — всего компонента `ExampleComponent`, где вызван `useState`.
Перерисовывается `ExampleComponent`, но
с помощью виртуального DOM сравниваются значения и изменяются только те части, которые действительно изменились.
Ответ кроется в структуре useState.
Это реальный код useState из React.
Из глобального объекта берётся `dispatcher` и вызывается `useState`.
Из этого кода сложно понять структуру.
Если копать глубже, то можно найти следующий код.
Берётся `hook`, функция `set` напрямую связывается с `queue` внутри `hook` с помощью `bind`.
(`bind` связывает `this` с существующей функцией, остальные аргументы передаются как аргументы функции, а возвращается новая функция с привязанным `this`)
Из этого кода всё равно сложно понять причину.
Давайте копнём ещё глубже
Мы видим, что начальное значение присваивается каждый раз. Это не объясняет, как сохраняется состояние.
Давайте копнём ещё глубже. `hook` выглядит подозрительно.
`currentlyRenderingFiber` и `workInProgressHook` — глобальные переменные.
Используя присвоение справа налево, реализован связный список.
Таким образом, структура хука, вероятно, выглядит так:
В начало добавляются новые значения.
Но всё равно непонятно, и после изучения других реализаций useState
оказалось, что не всегда вызывается `mountState`, а при перерисовке вызываются `updateState` и `rerenderState`.
Таким образом, структура такая, как описано выше, и в зависимости от события вызываются разные функции.
Если вы хотите посмотреть код напрямую, то можете найти его в `react/packages/react-reconciler/src/ReactFiberHooks.js`.
Комментарии0