отv16.3.0
Начните следующие три крючка жизненного цикла, отмеченные какUNSAFE
.
-
componentWillMount
-
componentWillRecieveProps
-
componentWillUpdate
Этому есть две причины:
-
Эти три хука часто используются неправильно, и теперь появляются лучшие альтернативы (здесь недавно добавленный
getDerivedStateFromProps
а такжеgetSnapshotBeforeUpdate
). -
React
отLegacy
Схема перенесена вConcurrent
После мода поведение этих хуков не будет таким, как раньше.
Эта статья начнется сReact
Проанализируйте эти два момента с точки зрения исходного кода.
В то же время благодаря изучению данной статьи вы сможете освоитьReact异步状态更新机制
принцип.
неправильно использованный крючок
Давайте сначала обсудим первый пункт, здесь мы используемcomponentWillRecieveProps
Пример.
мы частоcomponentWillRecieveProps
Внутренняя обработкаprops
влияние изменений. Некоторые ученики думают, что этот крючокprops
Запускается после изменения.
Действительно? Давайте посмотрим на исходный код.
Этот код изupdateClassInstance
метод:
if (
unresolvedOldProps !== unresolvedNewProps ||
oldContext !== nextContext
) {
callComponentWillReceiveProps(
workInProgress,
instance,
newProps,
nextContext,
);
}
ты можешь начатьздесьпосмотреть этот источник
вcallComponentWillReceiveProps
метод вызоветcomponentWillRecieveProps
.
Видно, что ключом к тому, стоит ли звонить, является сравнениеunresolvedOldProps
а такжеunresolvedNewProps
конгруэнтны, иcontext
изменять.
вunresolvedOldProps
когда компонент последний раз обновлялсяprops
,а такжеunresolvedNewProps
отClassComponent
передачаthis.render
вернутьJSX
серединаprops
параметр.
увидеть их引用
отличается. поэтому они全等比较
дляfalse
.
По этой причине,Каждое обновление родительского компонента вызывает обновление текущего компонента.componentWillRecieveProps
.
Подумайте, если вы когда-нибудь злоупотребляли им?
миграция схемы
Рассмотрим вторую причину:
React
отLegacy
Схема перенесена вConcurrent
После мода поведение этих хуков не будет таким, как раньше.
Давайте сначала разберемся, что такое шаблон? В чем разница между разными режимами?
От наследия к параллельному
отReact15
обновитесь доReact16
После этого исходный код сильно меняется, скажемReact
Рефакторинг может быть более подходящим.
Именно потому, что изменения настолько велики, некоторые функцииReact
Нестабильная производительность включает в себя три хука жизненного цикла, упомянутые выше.
Чтобы разработчики могли плавно перейти со старой версии на новую,React
Введено три режима:
-
legacy模式
-- пройти черезReactDOM.render
Созданное приложение включит этот режим. это текущийReact
способ использования. Этот режим может не поддерживать некоторые новые функции. -
blocking模式
-- пройти черезReactDOM.createBlockingRoot
Созданное приложение включит этот режим. открытая секцияconcurrent
функции схемы, перенесенные вconcurrent
Первый шаг узора. -
concurrent模式
-- пройти черезReactDOM.createRoot
Созданное приложение включит этот режим. Перспективная модель развития.
ты можешь начатьздесьСм. поддержку функций для различных режимов
concurrent模式
по сравнению с тем, что мы сейчас используемlegacy模式
Основное отличиеПреобразовать механизм синхронного обновления в асинхронное прерываемое обновление..
Далее мы обсудимReact
Как добиться异步更新
, и почему异步更新
поведение хука в случае и同步更新
разные.
Обновление синхронизации
мы можем использовать代码版本控制
аналогия更新机制
.
В отсутствие代码版本控制
Раньше мы постепенно наращивали функциональность в нашем коде. Кажется, все в порядке, пока мы не столкнемся с серьезной онлайн-ошибкой (красный узел).
Чтобы исправить эту ошибку, нам нужно сначала закоммитить предыдущий код.
существуетReact
, все проходятReactDOM.render
Все приложения создали состояние обновления одинаковым образом.
то есть все更新
синхронное исполнение, нет优先级
концепт, новый高优更新
(красные узлы) также необходимо ранжировать в других更新
Выполнить позже.
Асинхронное обновление
когда есть代码版本控制
, когда возникает срочная онлайн-ошибка, которую необходимо исправить, мы временно сохраняем модификацию текущей ветки, вmaster分支
Исправьте ошибки и срочно запустите.
Пройдено после выхода исправления ошибкиgit rebase
команда и开发分支
соединять.开发分支
Продолжается разработка версии с исправленными ошибками.
существуетReact
в, черезReactDOM.createBlockingRoot
а такжеReactDOM.createRoot
Созданное приложение будет обновлять состояние асинхронно, пока срок действия задачи не истек.
高优更新
(красный узел) прерывание в процессе低优更新
(синий узел), сначала завершите процесс рендеринга.
обращаться高优更新
после завершения,低优更新
на основе高优更新
из部分
или完整
Результаты снова обновляются.
Углубитесь в исходный код
существуетReact
В исходном коде каждый раз, когда вы инициируете更新
создастUpdate
объект, кратный одному и тому же компонентуUpdate
(A -> B -> C, как показано выше) начнется с链表
хранится в видеupdateQueue
середина.
Познакомьтесь с ними первыми数据结构
.
Update
Есть много областей, в настоящее время мы сосредоточены на следующих трех областях:
const update: Update<*> = {
// ...省略当前不需要关注的字段
lane,
payload: null,
next: null
};
Update
Зависит отcreateUpdate
возвращает метод, вы можете получить его изздесьВидетьcreateUpdate
исходный код
- полоса: представляет приоритет. то есть на картинке
红色
узел с蓝色
Разница узлов. - полезная нагрузка: обновить смонтированные данные. для
this.setState
созданный更新
,payload
дляthis.setState
параметры. - следующий: с другим
Update
Связано для формирования связанного списка.
updateQueue
Структура выглядит следующим образом:
const queue: UpdateQueue<State> = {
baseState: fiber.memoizedState,
firstBaseUpdate: null,
lastBaseUpdate: null,
shared: {
pending: null,
},
// 其他参数省略...
};
UpdateQueue
Зависит отinitializeUpdateQueue
возвращает метод, вы можете получить его изздесьВидетьinitializeUpdateQueue
исходный код
-
baseState
:更新
на основании чегоstate
Начинать. На фото выше版本控制
В примере ошибка высокого качества исправлена и отправлена послеmaster
,разноеcommit
на основеmaster
Филиал продолжает развиваться. здесьmaster
филиалbaseState
. -
firstBaseUpdate
а такжеlastBaseUpdate
:更新
на основании чегоUpdate
начать сfirstBaseUpdate
начатьlastBaseUpdate
Завершите формирование связанного списка. ЭтиUpdate
был в последний раз更新
из-за优先级
Недостаточно, чтобы осталось, как показано на картинкеA B C
. -
shared.pending
: одно или несколько из этого обновленияUpdate
сформированный связанный список.
вbaseUpdate
+ shared.pending
будет реализовано как это обновлениеUpdate
.
пример
понял数据结构
, то мы моделируем один раз异步中断更新
, чтобы раскрыть секреты, раскрытые в этой статье -componentWillXXX
ЗачемUNSAFE
.
в компонентеupdateQueue
Есть четыреUpdate
,в字母
представлятьUpdate
письма для обновления,数字
представлятьUpdate
приоритет, тем меньше число优先级
выше.
baseState = '';
A1 - B2 - C1 - D2
При рендеринге в первый раз优先级
1.B D
Недостаточный приоритет для пропуска.
чтобы убедиться, что更新
непрерывность первого пропущенаUpdate
(B
) и все последующиеUpdate
будет отображаться как второй разbaseUpdate
, независимо от их优先级
высокие и низкие, вотB C D
.
baseState: ''
Updates: [A1, C1]
Result state: 'AC'
Затем второй рендер,优先级
2.
из-заB
пропускается при первом рендере, поэтому после егоC
Полученные результаты рендеринга не будут отражены во втором рендеринге.baseState
середина. такbaseState
дляA
вместо последнего рендераResult state AC
. Это также для обеспечения更新
преемственности.
baseState: 'A'
Updates: [B2, C1, D2]
Result state: 'ABCD'
мы обнаруживаем,C
Появляется в обоих рендерах одновременноUpdates
, он представляет状态
будет обновлен дважды.
Если есть такой код:
componentWillReceiveProps(nextProps) {
if (!this.props.includes('C') && nextProps.includes('C')) {
// ...do something
}
}
вероятно, будет вызван дважды, что то же самое, что и同步更新
изReact
Нестабильная производительность!
По вышеуказанным причинам,componentWillXXX
отмечен какUNSAFE
.
Суммировать
Из-за ограниченного пространства, на этот раз мы сосредоточимся только наReact
Верхушка айсберга исходного кода.
Если вы хотите узнать большеReact
Исходный код, я рекомендую его вам здесь开源
,严谨
,易懂
Электронная книга React Source -Демистификация технологии React