Добро пожаловать на подпискуДемистификация технологии React
это скучный вопрос
Когда мне задали этот вопрос, моя первая реакция была - мне так скучно 🤷♂️
Если подумать, эм~, кажется, что все не так просто 🤔
Если вы выберете все сразуdiv
Затем пройдите и удалите,div
узлы-потомки также удаляются. Есть ли способ удалить только иерархические отношения всего дерева DOMdiv
А узлы?
Я задумался. . . . .
Zhihu написан React. React использует JSX для представления иерархии страниц. JSX будет преобразован Babel вReact.createElement
.
Когда код запускается, React на самом деле получаетReact.createElement()
Возвращаемое значение.
Вот и решение!
Нам просто нужно перезаписатьReact.createElement
метод, при встречеtype === 'div'
,мы будемtype
превратиться вReact.Fragment
, т.е. кладем всеdiv
узлы становятсяFragment
, то его можно удалить с сохранением иерархической связи дереваdiv
уже?
Давайте начнем! !
Как получить объект React
В этот раз я столкнулся с первой проблемой: Zhihu не выставил React на весь мир (бред, конечно нет 😠), как получить объект React?
К счастью, когда мы используемReact Dev Tools
час,Dev Tools
вставит глобальные переменные на страницу__REACT_DEVTOOLS_GLOBAL_HOOK__
, эта переменная станет ссылкойReact
а такжеDev Tools
мост.
один из нихrenderers
Атрибут относится к средству визуализации, используемому страницей, которое знакомо нам по веб-странице.React-DOM
(На стороне клиента, конечно, этоReact-Native
Ла)
мы нашли способfindFiberByHostInstance
Имя метода действительно появилосьFiber
шрифт! !
мы знаем,Fiber
Это наименьшая планируемая единица React (не спрашивайте, почему, просто спросите у Amway, я ее написал).Демистификация технологии React)
ЭтоfindFiberByHostInstance
Файл, в котором находится метод, должен иметь определения, связанные с React. Мы щелкаем правой кнопкой мыши, чтобы перейти к файлу, который определяет функцию,
искать в файле.createElement
Конечно же, мы нашли его. Нажмите на точку останова, обновите страницу и попробуйте~
Конечно же, он пришел, и все стало интереснее 😊😊😊
посмотриo.a
Что это, em~~ объект сChildren
,createElement
. . . . . .
Похоже, это объект React
Спешите сохранить с трудом заработанный объект React в глобале, а также кстати сохранить копию React.createElement.
Теперь отпустите точку останова,window.React
Он уже указал на React, используемый на домашней странице Zhihu.
Изменить метод React.createElement
мы знаем,React.createElementПервый параметр методаtype
(Не спрашивайте почему, спросите другую волну AmwayДемистификация технологии React), мы идем вРеагировать на документациюнайти вReact.Fragment
Определение.
if (typeof Symbol === 'function' && Symbol.for) {
const symbolFor = Symbol.for;
REACT_ELEMENT_TYPE = symbolFor('react.element');
REACT_PORTAL_TYPE = symbolFor('react.portal');
REACT_FRAGMENT_TYPE = symbolFor('react.fragment');
REACT_STRICT_MODE_TYPE = symbolFor('react.strict_mode');
REACT_PROFILER_TYPE = symbolFor('react.profiler');
REACT_PROVIDER_TYPE = symbolFor('react.provider');
// ...
}
Затем измените глобальную переменную
React.createElement = (type, ...args) => {
if (type === 'div') {
type = Symbol.for('react.fragment');
}
// originCreateElement才是正经的React.createElement
return originCreateElement(type, ...args);
}
Давайте Kangkang структуру страницы в это время
ok~~~ полный экран div set div (не нравится лицо), затем мы осторожно нажимаем кнопку «следовать», чтобы активировать любой компонентsetState
.
Затем настал момент стать свидетелем чуда. . .
За исключением корневого узла, другиеdiv
Все исчезло, и наконец восстановили освежающий интерфейс прошлого (большая ошибка)
Суммировать
Через эту скучную статью мы понимаем:
- React пожары каждый раз
setState
Обновления повторно обходят все дерево Fiber. (В противном случае он не будет нажимать кнопку для всей страницыdiv
исчезнувший) - Глубокое применение React.createElement.
- Слишком много Чжиху
div
охватывать
PS: если вы используете Chrome, код будет сжатformatted
Затем нажмите точку останова, обновите страницу и введите точку останова после того, как браузер зависнет, не сомневайтесь, это ошибка Chrome, на момент版本 81.0.4044.138(正式版本) (64 位)
Еще не исправлено, рекомендуется использовать версию разработчика ChromeChrome Canary