Решил немного углубиться в структуру объекта Fiber. Эти знания будут нужны для понимания работы алгоритмов React.
Первое поле ,которое нас встречает в типе Fiber исходного кода реакт - tag. Оно типизировано типом WorkTag и представляет собой перечисление числовых литералов от 0 до 29.
export type WorkTag = 0 | 1 | ... | 28 | 29;
Для каждого числа из перечисления существует константа со значением соответствующего числового литерала. Например:
export const FunctionComponent = 0;
Прежде ,чем попытаться дать определение этому полю ,посмотрим на другие константы ,которое оно может принимать:
Здесь можно заметить ,что Fiber хранит не тип ReactNode ,с которым он непосредственно связывается ,а способ создания этого ReactNode. Эту информацию он извлекает непосредственно из объекта ReactNode. Учитывая ,что ReactNode является типом-перечислением других типов ,свойства могут анализироваться разные для каждого типа.
Рассмотрим для простоты тип ReactElement ,который возвращается функциональными компонентами или методом render классовых. Он также может представляться элементом DOM ,созданным через React.createElement (или JSX-разметкой ,которая через babel все равно превратится в createElement). Нас будут интересовать 2 поля - $$typeof и type.
Сперва React определит ,что узел является ReactElement ,проверив $$typeof ,ведь для него он будет равен значению Symbol(react.element). Это позволяет React сразу же классифицировать ноду и понять ,как ее обрабатывать дальше.
Затем он посмотрит на поле type ,которое в случае ,если:
Но тут загвоздка. И Function и Class представляют собой тип function в рантайме javascript. Как React их различает? Все довольно просто ,у функции-конструктора есть prototype ,хранящий отличительные методы ,характеризующие его как класс компонента. Например ,prototype.render ,на который и ориентируется React при проверке.
Разобрались с тем ,как это поле заполняется. Кстати заполняется оно при создания нового Fiber - в процессе первичного рендеринга или на этапе реконсиляции при цикле обновлений ,если это требуется. Далее рассмотрим ,какую роль он играет в механизмах React?
На основе значения tag React выбирает подходящий алгоритм для работы с данным Fiber для дальнейшего обновления DOM. При анализе изменений ,React может сравнить tag и сразу же понять ,что например при его отличии от предыдущей версии нужно создать новый Fiber ,и анализировать другие свойства уже нет смысла ,тем самым сократив кол-во всевозможных проверок до одной и оптимизировать цикл.
Такая ситуация может произойти в результате изменения структуры элементов ,например ,при работе со списками или условным отображением. Если вдруг после рендеринга на позиции компонента <A /> вдруг встал элемент <div /> ,то именно такая ситуация и произойдет ,тк это ноды разного типа. Однако ,если для A указать key ,то он корректно сопаставится с Fiber и не будет перемонтирован. То есть key - это еще одно свойство ,на которое смотрит React при сравнении и учитывает это. Более детально key я разберу когда-нибудь потом ,однако сразу замечу ,что в структуре объекта Fiber это свойство также присутствует.
Для tag MemoComponent React ,например также пропустит ряд проверок ,речь идет о компонентах ,обернутых в memo. Это тоже важная часть оптимизации ,которую я рассмотрю когда-нибудь позже.
Мы поможем вам ее достичь!
310 000
единомышленников
инструменты
для увлекательного достижения