Интенсивное чтение "Что делает setState"

React.js

1. Введение

setStateЭто наиболее часто используемая команда фреймворка React, которая используется для обновления состояния, что также является эпохальной функцией фреймворка React.

ноsetStateфункцияreactПакет экспортируется, и как ониreact-dom react-native react-artЧто объединяет эти пакеты?

пройти черезhow-does-setstate-know-what-to-doЭта статья может раскрыть секрет.

2 Обзор

setStateфункция находится вReact.ComponentОн вызывается в компоненте, поэтому самая естественная ассоциация — логика обновления DOM находится в компоненте.reactРеализовать в упаковке.

ноreactно можетreact-dom react-native react-artЭти пакеты хорошо играют даже сreact-dom/serverСотрудничайте с запуском на стороне сервера, это точноreactПакет не содержит логики обновления DOM.

Таким образом, можно сделать вывод, чтоЛогика обновления пользовательского интерфейса, связанная с платформой, распространяется в связанных с платформой пакетах.reactПакет действует только как прокси.

Реактивный движок не находится в реактивном пакете

Начиная с версии 0.14 реакции код движка был извлечен из пакета реакции, а пакет реакции абстрагирует только общий интерфейс.

То есть пакет react определяет стандартный API модели, управляемой состоянием, в то время какreact-dom react-native react-artЭти пакеты являются конкретными реализациями на соответствующих платформах.

Конкретная реализация механизма рендеринга каждой платформы называетсяreconcilerПо этой ссылке вы можете увидетьreact-dom react-native react-artРеализации согласователя этих трех пакетов.

Это показывает, что пакет реагирования говорит вам только о том, какой синтаксис имеет React, а не о том, как его реализовать, поэтому нам нужно объединить пакет реагирования с react-xxx.

дляcontext, пакет реакции определяет только следующее:

// A bit simplified
function createContext(defaultValue) {
  let context = {
    _currentValue: defaultValue,
    Provider: null,
    Consumer: null
  };
  context.Provider = {
    ?typeof: Symbol.for("react.provider"),
    _context: context
  };
  context.Consumer = {
    ?typeof: Symbol.for("react.context"),
    _context: context
  };
  return context;
}

При специальном использованииreact-domа такжеreact-nativeКаким образом вы решаете?MyContext.Providerэтот API.

Это также показывает, что если вы не синхронизируете обновлениеreactа такжеreact-domверсии вы можете столкнуться с такой ошибкой:fail saying these types are invalid, так как определение API не соответствует реализации.

Как вызвать реализацию платформы setState

Реализация логики обновления UI для каждой платформы будет инкапсулирована вupdaterФункция, код будет добавлен, чтобы разные платформы для каждого компонентаupdaterвыполнить:

// Inside React DOM
const inst = new YourComponent();
inst.props = props;
inst.updater = ReactDOMUpdater;

// Inside React DOM Server
const inst = new YourComponent();
inst.props = props;
inst.updater = ReactDOMServerUpdater;

// Inside React Native
const inst = new YourComponent();
inst.props = props;
inst.updater = ReactNativeUpdater;

отличный отprops, updaterнельзя вызывать напрямую, потому что этот API используется механизмом реагирования вsetStateвызывается, когда:

// A bit simplified
setState(partialState, callback) {
  // Use the `updater` field to talk back to the renderer!
  this.updater.enqueueSetState(this, partialState, callback);
}

Отношения можно описать следующим образом:react -> setState -> updater <- react-domЖдать.

Hooks

Принцип крючков иsetStateАналогично при вызовеuseStateилиuseEffect, его внутренний вызов выглядит следующим образом:

// In React (simplified a bit)
const React = {
  // Real property is hidden a bit deeper, see if you can find it!
  __currentDispatcher: null,

  useState(initialState) {
    return React.__currentDispatcher.useState(initialState);
  },

  useEffect(initialState) {
    return React.__currentDispatcher.useEffect(initialState);
  }
  // ...
};

ReactDOM предоставляет__currentDispatcher(упрощенная версия):

// In React DOM
const prevDispatcher = React.__currentDispatcher;
React.__currentDispatcher = ReactDOMDispatcher;
let result;
try {
  result = YourComponent(props);
} finally {
  // Restore it back
  React.__currentDispatcher = prevDispatcher;
}

Видно, что принцип хуков тот же, что иsetStateВ основном то же самое, но нужно обратить вниманиеreactа такжеreact-domпрошел междуdispatch, хотя вы этого не видите. но этоdispatchДолжен соответствовать уникальному экземпляру React, поэтому хуки не позволяют загружать несколько экземпляров React одновременно.

а такжеupdaterТакой же,dispatchОн также может быть переписан различными реализациями платформы, такими какreact-debug-hooksпереписатьdispatcher.

В связи с необходимостью реализации обоихreadContext, useCallback, useContext, useEffect, useImperativeMethods, useLayoutEffect, useMemo, useReducer, useRef, useState, количество инженерных работ относительно велико, рекомендуется понимать базовую архитектуру, если только вы не хотите активно участвовать в построении экосистемы React.

3 Интенсивное чтение

В отличие от других статей по анализу React, в этой статье не слишком много анализируется основная проблема.reconcilerреализации, но задает фундаментальный вопрос: почемуsetStateотreactпакет, но реализация находится вreact-domвнутри? Как React достигает этой магии?

Благодаря этому вопросу мы узнали о возможностях абстракции React более высокого уровня, о том, как использовать пакет для формулирования спецификаций и использовать N пакетов для его реализации.

Сила интерфейса

В повседневном программировании интерфейс также имеет большую силу, вот несколько примеров.

Интерфейс компонента пользовательского интерфейса через три терминала

Из-за некоторых недостатков RN, Weex и Flux все больше и больше людей выбирают подход «реализация одной идеи с тремя терминалами» для создания компонентов пользовательского интерфейса на трех терминалах, который не только учитывает производительность, но и учитывает различия платформ Детали компонентов платформы настраиваются и оптимизируются.

Для реализации этой схемы самой большой проблемой является соглашение об интерфейсе. Необходимо убедиться, что три набора реализаций следуют одному и тому же набору интерфейсов API, чтобы бизнес-код можно было «написать для любой платформы и автоматически переносить на другие платформы».

Более распространенной практикой является использование набора унифицированных ограничений файла API для фиксации ввода и вывода компонентов, а также компонентов различных платформ для реализации конкретной платформы. Эта идея такая же, как React.

Конечно, и сами RN-фреймворки типичны для одного и того же интерфейса, реализованного на разных платформах, но они недостаточно тщательны, а взаимодействие между JS и Native приводит к производительности, которая не так хороша, как у оригинала.

Общий сервис запроса данных

Также популярны общие сервисы запросов к данным.Сглаживая синтаксис каждой базы данных, пользователи могут запрашивать данные различных типов баз данных через набор SQL.

В этом решении общий синтаксис запроса аналогичен API, определенному React, а фаза выполнения будет преобразована в диалект SQL каждой платформы базы данных.

Схема интеграции малых программ

Сейчас эта схема очень популярна. С помощью шаблона или синтаксиса на основе jsx можно публиковать одним щелчком мыши апплеты на различных платформах.

Это решение определенно абстрагирует набор общей грамматики, даже почти эквивалентныйreactа такжеreact-domСвязь между: Все грамматики, соответствующие спецификации, преобразуются в реализацию каждой платформы апплета.

4 Резюме

Эта подплатформенная схема реализации все же сильно отличается от кроссплатформенной схемы, например, виртуальная машина JAVA по сути представляет собой набор схем реализации. Реализация подплатформ может обеспечить максимальную производительность и опыт, а также имеет самые большие ограничения.Его API должен быть подмножеством всех платформ.

Кроме того, эту схему можно использовать не только для набора спецификаций, но и для реализаций на разных платформах, и даже для «реализаций на одной платформе».

Будь то компания или индустрия фестивалей с открытым исходным кодом, существует множество повторяющихся колес или платформ.Если технический комитет согласует набор спецификаций реализации платформы, и все будут следовать этой спецификации при разработке платформы, то лучше сделать конвергенцию. в будущем или первый шаг к конвергенции Первый шаг — унифицировать спецификацию API.

Оставьте мысленный вопрос: есть ли пользаsetStateИдеологический аргумент в пользу разделения спецификации и реализации? Добро пожаловать, чтобы оставить свой ответ.

Адрес обсуждения:Интенсивное чтение «Что делает setState» · Выпуск №122 · dt-fe/weekly

Если вы хотите принять участие в обсуждении, пожалуйста,кликните сюда, с новыми темами каждую неделю, выходящими по выходным или понедельникам. Интерфейс интенсивного чтения — поможет вам отфильтровать надежный контент.