пиши на фронт
Почему setState, потому что для всех большинство новичков или новичков, использующих React, напрямую соприкасаются с setState, и этот метод также может быть наиболее уязвимым методом работы. Поэтому, если вы хотите подробно разобраться, что делает setState в React, вам нужно копнуть немного глубже. В последней версии React 16 основная структура рендеринга React была обновлена один раз с предыдущей версии React на React Fiber. (PS: Эта статья написана для новичков и младших инженеров. Есть ошибки и недостатки, пожалуйста, укажите на исправления. Это кажется слишком низким, пожалуйста, объезд, спасибо.)
- Зачем обновлять?
- Зачем узнавать о волокне?
Не волнуйтесь, позвольте мне ответить вам медленно.До версии 16 React все еще использовал старую версию ядра рендеринга, и его процесс рендеринга завершался за один раз.Как вы это понимаете? Он будет проходить все ваши узлы Dom одновременно, в зависимости от сложности вашего приложения. Конечно, этот процесс в целом быстрее, но не исключается, что время ожидания в больших и сложных приложениях будет относительно большим, и это время основано на уровне мс. Для фронтенд-разработчика оптимизация производительности является одним из наиболее важных аспектов.Как мы все знаем, механизм рендеринга браузера является однопоточным, а это означает, что за определенный период времени можно выполнить только одну операцию. Когда ваше приложение слишком сложное, действий пользователя становится больше, а недостатки проявляются: зависание, зависание и даже вылеты страницы... Поэтому React будет обновлен до React Fiber.До обновления режим рендеринга был такой :
Предположим, ваша структура выглядит следующим образом: Компонент A => Компонент B => Компонент C/D/E Компонент D => Компонент F Рендеринг без архитектуры Fiber
Его устаревший режим рендеринга выглядит так:
После обновления до Fiber, как и при плавании, каждый период времени нужно выходить на берег, чтобы перевести дух, поэтому режим рендеринга становится следующим:
Дайверы время от времени приходили на берег, чтобы посмотреть, есть ли более важные дела.
Добавление обновлений компонентов оптоволокна будет проходить в два этапа: этап согласования и этап фиксации.
- На этапе согласования, на этом этапе React использует алгоритм сравнения, чтобы определить, какие компоненты необходимо обновить, помечает компоненты, которые необходимо обновить, а затем добавляет все компоненты, которые необходимо обновить, в массив, ожидая или выполняя задача обновления. Примечание: Этот этап может быть прерван, то есть во время этого этапа реакция обнаруживает, что есть поведение пользователя, или какие-то другие вещи будут прерваны.После выполнения события этот этап будет возобновлен.Да Сделать это опять таки.
- Этап фиксации, этот этап основан на обновленном массиве, сгенерированном на этапе согласования, обходе и обновлении DOM, этот этап выполняется один раз и не будет прерываться.
Через эти два этапа вы поймете, почему componentWillMount, componentWillReviceProps и componentWillUpdate ранее были помечены как небезопасные функции жизненного цикла, потому что на этапе согласования после прерывания он повторно запускается, что может вызвать это. ненужная трата ресурсов и производительности (вот более интересная проблема с голодом, умные студенты должны были догадаться, react пока не анонсировал решения).
Что такое волокно?
Волокно на самом деле является объектом. В исходниках Файбера есть такое описание
A Fiber is work on a Component that needs to be done or was done. There can be more than one per component.
Волокно является объектом, который должен быть выполнен записывающим компонентом, или обновление было завершено, компонент может соответствовать множеству волокон.
Далее, давайте посмотрим, как конкретно выглядит Fiber? Поскольку это объект, это должен быть шаблон {}. следующим образом:
{
tag,
key,
elementType,
type,
stateNode,
return,
child,
sibling,
index,
ref,
pendingProps,
memoizedProps,
updateQueue,
memoizedState,
firstContextDependency,
mode,
effectTag,
nextEffect,
firstEffect,
lastEffect,
expirationTime,
childExpirationTime,
alternate,
actualDuration,
actualStartTime,
selfBaseDuration,
treeBaseDuration
}
Дерево элементов React, созданное в функции рендеринга, создаст дерево узлов Fiber с той же структурой при первом рендеринге. Разные типы React Element соответствуют разным типам узлов Fiber. Работа элемента React обрабатывается соответствующим ему узлом Fiber.
Волокна имеют следующий приоритет:
Высокий приоритет прерывает выполнение задач с низким приоритетом для выполнения в первую очередь.
Элемент React может соответствовать более чем одному волокну, поскольку при обновлении волокна он будет клонировать новое волокно (альтернативное) из исходного волокна (текущего). Побочные эффекты двух отличий Fiber записываются на альтернативе. Следовательно, при обновлении компоненту будет соответствовать не более двух волокон.После обновления альтернативный узел заменит предыдущий текущий узел и станет новым текущим узлом.
Все эти свойства поддерживаются волокном в текущей версии v16.6.3.Подробности см. в исходном коде здесь.ReactFiber.js
setState
В официальной документации четко указано, что состояние следует рассматривать как неизменяемое, поэтому более уважаемым способом написания является не прямое setState, а его изменение через callback-функцию setState.
this.setState(() => {[key]: value});
Ладно, давайте замолчим, давайте перейдем к сегодняшней теме, setState. Когда вы будете писать проект, в файле index.js будут введены два файла, react, react-dom. setState в файле реакции выглядит так:
Когда ваше приложение рендерится в первый раз, самое главное обращать внимание на ход работы react-dom.Как упоминалось ранее, апдейтер внедряется позже, то есть при загрузке react-dom. Затем setState покажет вам, что это такое?
Глядя непосредственно на очередь setState, здесь требуются три параметра, и вы можете видеть, что это объект экземпляра, полезная нагрузка и функция обратного вызова. Здесь давайте сначала посмотрим, для чего используются четыре переменные жизни в начале, и мы можем угадать приблизительную идею по прямой семантике.
Q1: Волокно что-то получает через метод get?
А1:Можно видеть, что метод, реализованный исходным кодом, в сочетании с контекстом текущего вызывающего метода может знать, что текущий файбер получает значение _reactInternalFiber для текущего экземпляра. Что это за значение?Фактически, через соответствующий метод set текущий экземпляр и workInProgress передаются и присваиваются свойству _reactInternalFiber текущего экземпляра.
Q2: currentTime, чтобы получить текущее время?
- Сначала определите, выполняется ли рендеринг, если да, верните последнее время планирования.
- Если это не рендеринг, он проверит, остались ли какие-либо незавершенные работы, оставшиеся с прошлого раза.
- Если nextFlushedExpirationTime === NoWork || nextFlushedExpirationTime === Никогда, оцените приоритет.
- Пересчитать текущее время рендеринга как время планирования и вернуться;
- Если есть какие-либо остатки с прошлого раза, он сразу вернется к текущему времени планирования.
- rederingTime можно обновить в любой момент, currentSchedulerTime обновляется только тогда, когда нет новых задач
Q3: Получает ли expireTime время истечения? Что за черт?
- В это время он войдет в первое суждение, если условие, оценивая, есть ли в настоящее время время выполнения контекста, выполняется ли рендеринг или другие условия.
- Если существует expireContext, время истечения изменяется на текущее время выполнения контекста.
- Если время запланировано, определите, находится ли оно на стадии фиксации.Если да, установите его в качестве приоритета синхронизации, в противном случае назначьте его как время истечения следующего рендеринга.
- Если ни одно из вышеперечисленных условий не выполняется, будет рассчитан приоритет текущего экземпляра волокна.
- Оно делится на асинхронное и синхронное, и для расчета вызываются разные методы соответственно.После получения приоритета это то же самое, что и синхронное обновление.Создайте обновление и поставьте его в очередь, а затем вызовите sheuduleWork
- Здесь также будет интерактивная оценка обновления, которая должна отслеживать кратчайшее время ожидания интерактивного истечения срока действия. Это позволяет нам синхронно сбрасывать все интерактивные обновления, когда это необходимо.
- Наконец, верните текущее требуемое время истечения срока действия.
- Этот шаг и 2 шага могут быть объединены для расчета приоритета
Вопрос 4. Создает ли обновление очередь обновлений?
А4:Этот этап заключается в создании объекта обновления через createUpdate.
После ряда неописуемых процессов наконец можно выполнить следующую операцию.
первая часть
- Сначала оцените, существует ли только одно волокно.Если волокно только одно, пусть q1 равно этому значению, а затем q2 клонирует q1
- Если есть два волокна, q1 равно волокну.updateQueue текущего экземпляра, а q2 равно alter.updateQueue;
- Если ни у одного волокна нет очереди обновления. Затем оба q1 и q2 создают новые.
- Только одно волокно имеет очередь обновления. Клонируйте, чтобы создать новый.
- Оба волокна имеют очереди обновления. Короче говоря, и q1, и q2 должны иметь волокно.
Вторая часть
- Когда q1 и q2 равны, фактически в позиции находится только одно волокно, и это волокно вставляется в очередь обновления;
- Если одна из q1 и q2 является непустой очередью, необходимо обновить обе пары столбцов;
- Когда обе очереди q1 и q2 не пусты, последнее обновление в обоих списках будет одинаковым из-за общей структуры. Так что просто добавьте q1 в очередь обновлений;
- Наконец, обновите указатель lastUpdate для q2.
Последний шаг — использовать метод scheduleWork() для окончательного обновления. В этом методе сегментированные обновления выполняются на основе приоритета.
- Сначала вызовите метод scheduleWorkToRoot(), обновите приоритет волокна, перейдите к родительскому пути корневого компонента и обновите приоритет дочернего компонента.
- Обновляет счетчик незавершенных асинхронных работ для ранее незапланированных взаимодействий.
- Обновления ожидающих асинхронных рабочих средств для текущего взаимодействия.
- Мониторинг изменений в списке обновления, вернитесь в root.
Затем, на этапе фиксации, выполнение завершается за один раз. Ваш DOM обновлен. Сказав так много, это может быть выполнено всего за несколько десятков миллисекунд... как ниже
На этом весь процесс setState завершен.
Резюме: Эту статью я начал писать впервые, местами она может быть не очень точной, а может быть немного многословной, но мне нравится. Как говорится, начало всего сложно, но и процесс труден, а конец еще труднее. То же самое относится и к коду: если вы продолжите в том же духе, у вас будет шейный спондилез. Что не так с этой статьей, я также хотел бы попросить всех великих богов указать, что я не буду ее менять, я сохраню ее в своем сердце. Вышеизложенное - мое понимание setState. Я надеюсь помочь вам понять Принцип и механизм реакции в направлении.