Менеджство переднего государства я понимаю

внешний интерфейс

Здравствуйте, давно не обновлялся, сегодня мы поговорим об истории фронтенд-управления состоянием~

предисловие

Мы знаем, что на ранней стадии фронтенд-разработки веб-страницы html только статичны, и любые небольшие изменения означают новую страницу; после этого появились iframe и XMLHttpRequest, которые реализовали асинхронную частичную загрузку и значительно улучшили пользовательский опыт; jQuery , с использованиемимперативОднако, когда приложение становится сложным, его трудно поддерживать; пока в последние годы, от рождения Angular до более позднего React, Vue не запускался один за другим, и различные технические фреймворки не возникали бесконечным потоком. , кроме Vuex, который знаком пользователям Vue, также появились React и Redux, Mobx, Rxjs и другие отличные решения для хранения и управления данными, и это реальная концепция фронтенд-управления состоянием.

Следует сказать, что появление SPA еще больше способствует разделению внешнего и внутреннего интерфейса.Внешнему интерфейсу больше не нужно отображать страницу, запрашивая HTML, возвращаемый URL-адресом, а генерирует DOM, загружая и анализируя JS, и самостоятельно реализует рендеринг контента.В середине этого процесса,управляемый даннымимысли также глубоко укоренились в сердцах людей.

Так называемый data-driven означает, что представление генерируется на основе данных, и мы можем обрабатывать DOM, модифицируя данные, что также типично.декларативныйпрограммирование. Взяв за пример React, мы можем легко обновить UI, изменив состояние, но есть проблема, у React нет никаких ограничений на слой данных, то есть любой компонент может изменить код слоя данных, что приносит проблема, когда на уровне данных возникает особая ситуация, трудно быстро найти и решить проблему, так как же управлять общедоступным состоянием в компоненте представления?

В это время команда Facebook предложила идею Flux, которая направлена ​​на решение проблемы все более сложной внутренней логики MVC и тяжелой логики в сложных сценариях с архитектурного уровня. Так что же такое архитектура Flux?

Идея Flux и ее реализация

В официальной документации Vuex есть интересное предложение: «Архитектура Flux похожа на очки: вы поймете, когда она вам понадобится».

Ну, это все еще неясно, поэтому давайте сначала разберемся с некоторыми основными понятиями Flux. (В качестве примера возьмем официальную реализацию Facebook)

Flux делит приложение на четыре части, среди которых:Уровень представления View, действие сообщения, отправленное уровнем представления, диспетчер, используемый для получения действий и выполнения функции обратного вызова, и хранилище, используемое для хранения состояния приложения..

Из рисунка выше видно, что этоодносторонний потокПроцесс: пользователь может инициировать действие только для изменения состояния, и состояние приложения также должно быть помещено в хранилище для унифицированного управления, а некоторые определенные операции могут выполняться путем прослушивания действия. Любое изменение состояния неотделимо от инициации Action и отправки Dispatcher, так что мы можем легко записать каждое изменение состояния. Это также основная концепция дизайна Flux.После этого появилось все больше и больше практик Flux.Далее давайте возьмем процесс разработки управления состоянием React в качестве примера, чтобы увидеть, как Redux управляет состоянием.

(Если вас интересует Flux, вы можете продолжить чтение статьи Руан Ифэн.Начало работы с архитектурой Flux. )

Redux

Когда React только появился, не было Redux, и мы могли управлять состоянием компонентов только через состояние, чего было достаточно в большинстве случаев, но как только приложение стало сложным, состояние все равно стало трудно поддерживать. Затем на него повлиял Flux, и в этой среде появился Redux.

Во-первых, Redux имеет три принципа:Единый источник достоверной информации, состояние только для чтения, использование чистых функций для выполнения модификаций.. Первые два легко понять, а что касается третьего, то вы должны знать, что React следует неизменности данных, то есть никогда не модифицирует свойства исходного объекта, а в исходном коде Redux только сравнивает места хранения старых и новые объекты.Независимо от того, совпадают ли старые и новые объекты, это означает, что свойства состояния не могут быть изменены напрямую, и каждый раз может быть возвращено только новое состояние. Таким образом, мы можем думать о Redux как о Reduce + Flux, а Reduce — это чистая функция, упомянутая выше.

Кроме того, в Redux есть важная концепция, называемая промежуточным программным обеспечением.

Промежуточное программное обеспечение в Redux предоставляет точку расширения после того, как действие инициировано и до того, как оно достигнет редюсера, что показано на одном рисунке:

preview

Видно, что при использовании промежуточного программного обеспечения промежуточное программное обеспечение будет соответствующим образом обрабатывать инициированные действия и, наконец, передавать их редьюсеру для выполнения. Допустим, нам нужно каждый раз печатать лог перед запуском Action, тогда мы можем вынуть метод Dispatch и переписать его, наверное, вот так:

let next = store.dispatch
store.dispatch = function dispatchLog(action) {  
  console.log('log', action) 
  next(action) 
}

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

Тогда почему промежуточное программное обеспечение должно быть разработано в этом промежуточном программном обеспечении = (сохранить) => (следующий) => (действие) => {[вернуть следующий (действие)]} многоуровневый метод записи с карри, в исходном коде есть метод applyMiddleware Используется для добавления промежуточного программного обеспечения, основной код, вероятно, выглядит следующим образом:

let store = createStore(reducers);
let dispatch;
// 这里第一次执行返回了一个存放可以修改dispatch函数的数组chain [f(next)=>acticon=>next(action)]
// 这个函数接收next参数 就是在中间件间传递的diapatch方法
let chain = middlewares.map(middleware => middleware({
  getState: store.getState, // 因为闭包 执行中间件的时候store不会更新
  dispatch: action => dispatch(action)
}));
// 调用原生的dispatch重写dispatch逻辑 只有最后一个中间件会接受真实的dispatch方法
dispatch = compose(...chain)(store.dispatch);
return {
  ...store,
  dispatch
}

Здесь вы можете видеть, что дизайн промежуточного программного обеспечения действительно очень умный, с использованием структуры каррирования.Он может легко получить доступ к тому же хранилищу, а также может взаимодействовать с методом компоновки для накопления параметров для достижения эффекта отложенного выполнения.Описание метода compose не приводится, в основном для интеграции промежуточного ПО справа налево через метод Reduce.

На самом деле в содержании исходного кода Redux есть и другие места, которыми стоит смаковать.Я напишу его позже, когда будет возможность.Далее посмотрим на свежее лицо.

Менеджер состояния React следующего поколения

Начиная с React16, все использовали хуки один за другим.Нет никаких сомнений, что появление хуков в определенной степени решило проблему функционального повторного использования между компонентами.Инкапсуляция и повторное использование этой логики действительно восхитительно, но есть еще некоторые проблемы, проблемы, такие как обмен данными. hox, получивший название диспетчера состояний React следующего поколения, предназначен для решения подобных проблем.

Зайдите на Github проекта, особенности здесь очень интересные:Только один API; использование пользовательских хуков для определения моделей; идеальное использование TypeScript; поддержка нескольких источников данных.. Я должен сказать, что этот API очень привлекателен, давайте посмотрим на официальный пример:

// 定义Model
import { createModel } from 'hox';
/* 任意一个 custom Hook */
function useCounter() {
  const [count, setCount] = useState(0);
  const decrement = () => setCount(count - 1);
  const increment = () => setCount(count + 1);
  return {
    count,
    decrement,
    increment
  };
}
export default createModel(useCounter)
--------------------------------------------------------------------------------------------
// 使用Model
import { useCounterModel } from "../models/useCounterModel";

function App(props) {
  const counter = useCounterModel();
  return (
    <div>
      <p>{counter.count}</p>
      <button onClick={counter.increment}>Increment</button>
    </div>
  );
}
// 这个时候useCounterModel 是一个真正的 Hook,会订阅数据的更新。也就是说,当点击 “Increment” 按钮时,会触发 counter model 的更新,并且最终通知所有使用 useCounterModel 的组件或 Hook。

CreateModel здесь аналогичен использованию HOC. Его функция заключается в реализации совместного использования данных. Вероятно, принцип заключается в том, что публикация-подписчик реализуется внутри. Всякий раз, когда модель повторно отображается, ее подписчики будут уведомлены о повторном отображении. Заинтересованные детской обуви, возможно, пожелают перейти непосредственно к исходному коду, его основного содержания не так много.

(На самом деле, когда я увидел hox, я обнаружил, что он немного похож на небольшую программную версию подключаемого модуля управления состоянием, который я написал ранее. Это API для глобального обмена данными. Здесь я дерзко разместил Github. адрес.createStore. )

Суммировать

От зарождения управления состоянием фронтенда до анализа процесса реализации React я кратко поделился некоторыми собственными мнениями.Если в тексте есть неточности, прошу обменяться и поправить меня.

Наконец, с 520, спасибо за чтение!