Анализ внешнего управления состоянием

внешний интерфейс React.js Vuex Redux

Статья впервые опубликована на:GitHub.com/US TB-Вуд, умри, о ты…

написать впереди

Развитие интерфейсных технологий меняется с каждым днем, и появление vue, react, angular и т. д. принесло нам новый опыт разработки. Однако с инновациями в технологиях и повышением сложности интерфейсных страниц появились соответствующие решения для хранения и управления данными, такие как localStorage, eventBus, vuex, redux, mobx, rxjs и т. д., поэтому необходимо изучить государственное управление. Так что я недавно потратил некоторое время на изучение этого. В процессе анализа могут быть отклонения в собственном понимании или различия в вашем понимании.Вы можете оставить комментарий или написать мне в личные сообщения.

Эта статья будет заключаться из следующих разделов:

  1. представление на основе данных
  2. Межкомпонентный обмен данными и шина событий
  3. Поток данных одного элемента (vuex && redux)
  4. лучше мобкс
  5. Реализовать супер простую версию redux и react-redux

представление на основе данных

В настоящее время самые популярные интерфейсы React и Vue, используемые дизайнерские идеи, представляют собой представления, управляемые данными, то есть UI = f (состояние).При изменении страницы вам не нужно заботиться об изменениях DOM, только изменения состояния. Процесс сопоставления состояния с пользовательским интерфейсом обрабатывается фреймворком. Для решения проблем с производительностью был создан Virtual DOM. С помощью Virtual DOM представления, управляемые данными, можно просто разбить на четыре этапа:

  • Изменения данных, создание нового виртуального DOM
  • Сравните сходства и различия между новым виртуальным DOM и старым виртуальным DOM с помощью алгоритма сравнения.
  • Создание разницы между старыми и новыми объектами (патч)
  • Перебирать объекты diff и обновлять DOM

С react и vue процесс state => UI имеет хорошую практику, но наоборот,Как разумно изменить состояние в пользовательском интерфейсе, стало новой проблемой.. С этой целью Facebook предложил идею потока. Подробнее см. в статье Руан Ифэн.Начало работы с архитектурой Flux. Проще говоря, Flux — это архитектурная идея, она считает, что есть некоторые проблемы с предыдущей инфраструктурой MVC, поэтому намерена использовать новое мышление для управления потоком данных.

Межкомпонентный обмен данными и шина событий

Данные можно просто разделить на две части: данные по компонентам и данные внутри компонентов. Большая часть данных в компоненте связана с пользовательским интерфейсом, например, установлен ли флажок переключателя или нажата кнопка. Их можно назвать внутрикомпонентными данными о состоянии. В реакции есть концепция, называемая кукольным компонентом, и данные, хранящиеся в нем, являются данными состояния в компоненте. На самом деле, многие библиотеки компонентов пользовательского интерфейса на рынке, такие как дизайн элементов и муравьев, предоставляют марионеточные компоненты. Другой тип данных — кросс-компонентные данные.Например, родительский компонент вызывает отключение дочернего компонента.Как только мы сталкиваемся с взаимодействием кросс-компонента, проблемы, с которыми мы сталкиваемся, начинают усложняться. В настоящее время необходим механизм для управления связью между родительскими и дочерними компонентами и одноуровневыми компонентами. Родительский компонент дочернему компоненту является передачей реквизита.То, как дочерний компонент реагирует на родительский компонент, заключается в том, что родительский компонент передает функцию обработки дочернему компоненту, который вызывается дочерним компонентом, так что данные передается из параметра функции в родительский компонент. Метод обработки Vue заключается в том, что дочерний компонент передает данные из параметра функции родительскому компоненту через функцию $emit, а родительский компонент получает вызов.

EventBus — это центральная коммуникация, а provider — это объект или функция, которая возвращает объект. Этот объект содержит свойства, которые можно внедрить в его потомков:

Вариантами ввода могут быть: массив строк или объект. Затем используйте введенное значение в качестве ввода данных:

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

Поток данных одного элемента (vuex && redux)

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

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

Redux подчеркивает три основных принципа:

  • уникальный источник данных
  • сохранить состояние только для чтения
  • Изменения данных могут быть сделаны только с помощью чистых функций

В todo-list, например, код размещен на github:Github

Уникальный источник данных:Уникальный источник данных означает, что данные о состоянии приложения должны храниться только в одном хранилище. Дерево состояний Store приложения todo-list выглядит следующим образом:

{
    todos: [
        {
            text: 'First todo',
            completed: false,
            id: 0
        },
        {
            text: 'Second todo',
            completed: false,
            id: 1
        }
    ],
    filter: 'all'
}

Держите состояние читабельным:Чтобы изменить состояние Store, это необходимо сделать, отправив объект действия. Согласно UI=render(state), для управления рендерингом пользовательского интерфейса необходимо изменить состояние приложения, но способ изменения состояния заключается не в изменении значения состояния, а в создании нового объекта состояния. и верните его в Redux, а Redux выполнит новое состояние сборки.

Изменения данных могут быть сделаны только с помощью чистых функций:Редюсер должен быть чистой функцией, и формат каждой функции редуктора следующий: редуктор(состояние, действие):

import {ADD_TODO, TOGGLE_TODO, REMOVE_TODO}from './actionTypes.js';

export default (state = [], action) => {
  switch(action.type) {
    case ADD_TODO: {
      return [
        {
          id: action.id,
          text: action.text,
          completed: false
        },
        ...state
      ]
    }
    case TOGGLE_TODO: {
      return state.map((todoItem) => {
        if (todoItem.id === action.id) {
           return {...todoItem, completed: !todoItem.completed};
        } else {
          return todoItem;
        }
      })
    }
    case REMOVE_TODO: {
      return state.filter((todoItem) => {
        return todoItem.id !== action.id;
      })
    }
    default: {
      return state;
    }
  }
}

Давайте используем картинку с официального сайта, чтобы представить следующий vuex:

Можно сказать, что Vuex — это инструмент управления состоянием, специально разработанный для Vue. В отличие от Redux, который использует неизменяемые данные для представления состояния, в Vuex нет редуктора для создания нового состояния взамен старого, а состояние в Vuex можно изменить. Причина этого связана с механизмом работы Vue.Vue реализует двустороннюю привязку представления и данных на основе геттера/сеттера в ES5.Поэтому изменение состояния в Vuex может быть уведомлено соответствующей инструкцией в представлении. через сеттер для реализации обновления представления.

Состояние в Vuex поддается изменению, и способ изменения состояния — не действия, а мутации. Единственный способ изменить состояние в хранилище Vuex — отправить мутацию.

Поток данных vuex выглядит просто:

  • Запустите действие в представлении и передайте необходимые параметры в соответствии с реальной ситуацией.
  • Запустите нужную мутацию в действии и измените состояние в функции мутации
  • Двусторонняя привязка через геттер/сеттер автоматически обновит соответствующее представление.

лучше мобкс

MobX делает управление состоянием простым и расширяемым за счет прозрачного применения функционального реактивного программирования (TFRP). Ниже приведена блок-схема mobx:

Сравнивая mobx и redux, есть небольшая разница: если redux воплощает в себе функциональное программирование, то mobx воплощает в себе больше объектно-ориентированных функций. mobx состоит из нескольких пунктов:

  • Наблюдаемый. Его состояние является наблюдаемым, будь то примитивный тип данных или ссылочный тип данных, его можно преобразовать в наблюдаемое значение, используя (@)observable в MobX. источник
  • Реакции. Он содержит различные концепции, основанные на обновлении наблюдаемых данных, приводящем к вычисляемому значению (вычисляемым значениям), или отправке сетевых запросов и обновлении представлений и т. д., все они относятся к категории ответа, которая также является реактивным программированием (Reactive Programming ) в JavaScript приложение .
  • Действия. Он эквивалентен источнику всех ответов, таких как действия пользователя в представлении или изменения наблюдаемых данных, вызванные ответом на сетевой запрос.

Реализовать упрощенную версию redux и react-redux

Простая реализация методов redux createStore, диспетчеризации, подписки, редуктора, getState.

function createStore (reducer) {
  let state = null
  const listeners = []
  const subscribe = (listener) => listeners.push(listener) // 观察者模式实现监控数据变化
  const getState = () => state
  const dispatch = (action) => { //用于修改数据
    state = reducer(state, action) // reducer接受state和action
    listeners.forEach((listener) => listener())
  }
  dispatch({}) // 初始化 state
  return { getState, dispatch, subscribe } // 暴露出三个方法
}

Простая реализация методов react-redux Provider, connect, mapStateToProps, mapDispatchToProps.

Реализуйте метод Provider:

export class Provider extends Component {
  static propTypes = {
    store: PropTypes.object,
    children: PropTypes.any
  }

  static childContextTypes = {
    store: PropTypes.object
  }

  getChildContext () {
    return {
      store: this.props.store
    }
  }

  render () {
    return (
      <div>{this.props.children}</div>
    )
  }
}

Это будет работать

<Provider store={store}>
    
</Provider>

Оберните корневой компонент.

Реализуйте метод подключения и согласитесь на передачу mapStateToProps и mapDispatchToprops:

export const connect = (mapStateToProps, mapDispatchToProps) => (WrappedComponent) => {
  class Connect extends Component {
    static contextTypes = {
      store: PropTypes.object
    }

    constructor () {
      super()
      this.state = {
        allProps: {}
      }
    }

    componentWillMount () {
      const { store } = this.context
      this._updateProps()
      store.subscribe(() => this._updateProps())
    }

    _updateProps () {
      const { store } = this.context
      let stateProps = mapStateToProps
        ? mapStateToProps(store.getState(), this.props)
        : {} // 防止 mapStateToProps 没有传入
      let dispatchProps = mapDispatchToProps
        ? mapDispatchToProps(store.dispatch, this.props)
        : {} // 防止 mapDispatchToProps 没有传入
      this.setState({
        allProps: {
          ...stateProps,
          ...dispatchProps,
          ...this.props
        }
      })
    }

    render () {
      return <WrappedComponent {...this.state.allProps} />
    }
  }
  return Connect
}

Суммировать

Если стек технологий проекта основан на vue, vuex для управления состоянием, несомненно, является лучшим выбором. Но если стек технологий основан на React, выбор между redux и mobx — вопрос личного мнения, и мудрые видят мудрость. Причиной выбора mobx может быть то, что процессов не так много, как redux, и для изменения состояния приходится обращаться к нескольким файлам, чтобы найти код. Кроме того, стоимость обучения невелика, и вы можете начать работу, прочитав документацию. Но недостаток в том, что он слишком бесплатный, и в нем очень мало условностей, из-за чего делать масштабные проекты немного безвкусно. Но редукс накладывает на разработчиков множество ограничений, но эти ограничения не так-то просто написать беспорядочно при выполнении больших проектов.

Справочная статья

китайская документация vuex

редукционная китайская документация

Говоря об управлении состоянием внешнего интерфейса (часть 1)

Дважды подумайте о внешнем управлении состоянием

Управление внешними данными и выбор интерфейсной платформы

Можете обратить внимание на мой паблик-аккаунт «Muchen Classmate», фермера на гусиной фабрике, который обычно записывает какие-то банальные мелочи, технологии, жизнь, инсайты и срастается.