Рубрики
Без рубрики

Исследуя то, что и то почему redux

Питер Мбануго, исследуя то, почему redux “Что в мире redux и зачем мне это нужно?” Я спросил себя в этом вопросе, когда я начал учиться построить одно страницу (SPA), чтобы включить богатое взаимодействие на моем Программы. У SPA имеет возможность

Автор оригинала: FreeCodeCamp Community Member.

Питер Мбануго

Я спросил себя в этом вопросе, когда начал учиться построить одностраничные приложения (SPA), чтобы включить богатое взаимодействие в моих приложениях. SPA имеет возможность повторно отображать разные части пользовательского интерфейса, не требуя отключения сервера.

Это достигается путем отделения различных данных, которые представляют состояние применения, из презентации этих данных.

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

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

Проблема

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

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

С разделением просмотров от моделей данные передаются из модели на вид. Если есть изменения, основанные на взаимодействия пользователя, это обновит модель, и это обновление модели может вызвать обновление другому модели, а также обновить другой компонент просмотра, который также может вызвать обновление в модели.

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

Прицел

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

Решение: однонаправленный поток данных и единый источник правды

Компоненты View должны прочитать данные из этого единственного источника и не сохранять свою собственную версию одного и того же состояния отдельно. Следовательно, необходимость в Один источник правды Отказ

На Facebook они хотели проще прогнозировать изменения государства и так привыкли с рисунком под названием Flux Отказ Flux – это шаблон слоя данных для управления потоком данных. Он предусматривает, что данные должны течь только в одном направлении, с состоянием приложения, содержащееся в одном месте, – источник правды – и логика для изменения состояния только в одном месте.

Поток

Диаграмма выше описывает поток данных в потоке:

  • Данные потоки из магазин – Источник истины – к Вид Отказ Просмотр читает данные и представляет его пользователю, пользователю взаимодействует с различными компонентами представления, и если им нужно изменить состояние приложения, они выражают свое намерение сделать это через Действие Отказ
  • Действие захватывает способы того, как все может взаимодействовать с вашим приложением. Это простой объект с помощью поля «типа» и некоторыми данными. Диспетчер отвечает за излучение действия в магазин. Он не содержит логику, чтобы изменить состояние, а скорее сам магазин делает это внутренне.
  • Вы можете иметь кратные магазины, каждый из которых содержит данные для различного домена приложения. Магазин отвечает на действия, относящиеся к государству, которое он поддерживает. Если он обновляет состояние, он также уведомляет представления, связанные с этим магазином, испуская событие.
  • Вид получает уведомление и извлекает данные из магазина, а затем повторно рендеры. Когда государство необходимо снова обновлять, он проходит через тот же цикл, что позволяет легко рассуждать о вашем приложении и внесении предсказуемых изменений состояния.

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

Redux Есть различные реализации этой картины. У нас есть FluxXor , Flummox , Рефлюкс , и больше. Но Redux выделяется выше над ними всех.

Redux взял концепции потока и превратился в его создание предсказуемой государственной библиотеки управления.

Дэн Абрамов, создатель Redux, создал его с намерением получить лучшую поддержку инструментов разработчиков, Горячая перегрузка и время путешествия отладки При этом сохраняя предсказуемость, которая поставляется с потоком. Redux пытается сделать государственные мутации предсказуемыми.

Redux, следуя по стопам flux, имеет три концепции:

  • Один источник правды : Я упомянул о необходимости этого. Redux имеет то, что он называет магазин Отказ Магазин является объектом, который содержит все ваше состояние приложения. Различные части состояния хранятся в дереве объекта. Это облегчает реализацию отменить/повторить.

Например, мы можем хранить и отслеживать элементы в корзине для покупок, а также в текущем выбранном продукте с redux, и это может быть смоделировано в магазине следующим образом:

{        "cartItem" : [            {                "productName" : "laser",                "quantity" : 2            },            {                "productName" : "shirt",                "quantity" : 2            }        ],        "selectedProduct" : {            "productName" : "Smiggle",            "description" : "Lorem ipsum ... ",            "price" : "$30.04"        }    }
  • Государство готовитно : Состояние не может быть изменено непосредственно по представлению или любому другому процессу (возможно, в результате обратного вызова сетевого вызова или другого события). Для того, чтобы изменить состояние, вы должны выразить свое намерение, испуская действие. Действие – это простой объект, описывающий ваше намерение, и он содержит свойство типа и некоторые другие данные. Действия могут быть зарегистрированы и позже воспроизведены, что делает его хорошим для целей отладки и тестирования.

После нашей корзины корзины мы можем выстрелить действие следующим образом:

store.dispatch({      type: 'New_CART_ITEM',      payload: {                   "productName" : "Samsung S4",                   "quantity" : 2                }    })    dispatch(action) emits the action, and is the only way to trigger a state change. To retrieve the state tree, you call store.getState().
  • Редуктор : Редукторы несут ответственность за выяснение того, какие изменения государства должны произойти, а затем преобразовывать его, чтобы отразить новые изменения. Редуктор – это чистая функция, которая принимает в предыдущем (текущее состояние, необходимо изменить) и действие, определяет, как обновить состояние на основе типа действия, преобразует его и возвращает следующее состояние (обновленное состояние).

Продолжая при примере нашей корзины, давайте скажем, мы хотим добавить новый предмет в корзину. Мы отправляем действие типа New_cart_item И, в пределах редуктора, мы определяем, как обрабатывать этот новый запрос на изменение, чтение через тип действия и действуя соответственно.

Для корзины покупок будет добавлять новый продукт в корзину:

function shoppingCart(state = [], action) {      switch (action.type) {        case 'New_CART_ITEM':          return [...state, action.payload]        default:          return state      }    }

Что мы сделали, было возвращение нового государства, которое является коллекцией старых корзину предметов, в дополнение к новому от действия. Вместо того, чтобы мутировать предыдущее состояние, вы должны вернуть новый государственный объект, и это действительно помогает со временем отладки путешествий.

Есть вещи, которые вы никогда не должны делать внутри редуктора, и они являются:

  • Мутируйте свои аргументы.
  • Выполните побочные эффекты, такие как вызовы API и переходы маршрутизации.
  • Вызовите не чистые функции.

Практический пример

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

Чтобы настроить, запустите следующие команды в терминале:

$ git clone git@github.com:StephenGrider/ReduxSimpleStarter.git    $ cd ReduxSimpleStarter    $ npm install

Мы только что клонировали шаблон стартера для того, что мы будем строить в этом разделе. Мы настроили RECT и загруженные пакеты Redux и React-Redux NPM. Мы будем создавать приложение, которое позволяет нам делать короткие заметки как делать товары или ключевые слова, которые напоминают нам о чем-то.

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

Создайте новый файл под названием Типы.js в ./src/cone Со следующим контентом:

export const FETCH = 'FETCH';    export const CREATE = 'CREATE';    export const DELETE = 'DELETE';

Далее нам нужно определить действия и отправлять их при необходимости. Создатели Действия – это функции, которые помогают создавать действия, и результат передается Отправка () Отказ

Изменить index.js Файл в папке действий со следующим содержимым:

import { FETCH, DELETE, CREATE } from './types';
    export function fetchItems() {      return {        type: FETCH      }    }
    export function createItem(item) {      let itemtoAdd = {        [Math.floor(Math.random() * 20)]: item      };
      return {        type: CREATE,        payload: itemtoAdd      }    }
    export function deleteItem(key) {      return {        type: DELETE,        payload: key      }    }

Мы определили три действия для создания, удаления и извлечения элементов из магазина. Далее нам нужно создать редуктор. Math.floor (math.random () * 20 используется для назначения уникального ключа к добавлению нового элемента. Это не оптимально, но мы будем использовать его здесь, просто ради этой демонстрации.

Добавьте новый файл в каталоге редуктора под названием item-redeber.js :

import _ from 'lodash';    import { FETCH, DELETE, CREATE } from '../actions/types';
    export default function(state = {}, action) {      switch (action.type) {        case FETCH:          return state;        case CREATE:          return { ...state, ...action.payload };        case DELETE:          return _.omit(state, action.payload);      }
      return state;    }

Определенным редуктором, нам нужно подключить его к нашему приложению, используя Combinerrever () функция.

Внутри папки редуктора, откройте и отредактируйте файл index.js :

import { combineReducers } from 'redux';    import ItemReducer from './item-reducer';
    const rootReducer = combineReducers({      items: ItemReducer    });
    export default rootReducer;

Мы передаем редуктор, который мы создали для Комбинированный препарат Функция, где ключ является частью состояния, за которого редуктор несет ответственность за.

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

С Комбинергер Функция, мы говорим Redux, как создать состояние нашего приложения. Таким образом, думая и проектирование того, как моделировать состояние вашего приложения в Redux – это то, что вы должны сделать заранее.

С настройкой redux о том, как управлять нашим состоянием, следующая вещь – подключить вид (который управляется реагированием) для redux.

Создать новый файл item.js внутри Компоненты каталог. Это будет умный компонент, потому что он знает, как взаимодействовать с Redux для чтения состояния и запрашивать изменения состояния.

Добавьте содержимое ниже в этот файл:

import React, { Component } from 'react';    import { connect } from 'react-redux';    import * as actions from '../actions';
    class Item extends Component {      handleClick() {        this.props.deleteItem(this.props.id);      }
      render() {        return (          
  • {this.props.item}
  • ); } }
        export default connect(null, actions)(Item);

    Этот компонент отображает элемент и позволяет нам удалять его. Подключиться () Функция принимает компонент реагирования в глухую состояние (он не имеет знания о redux, ни как взаимодействовать с ним) и производит умный компонент. Он связывает создателей действия к компоненту, так что, если вызывается Action Creator, возвращаемое действие отправляется в редукторы.

    Мы также сделаем второй интеллектуальный компонент, который будет представлять предыдущий компонент в виде списка элементов, а также позволит нам добавлять новые элементы.

    Обновите файл app.js Внутри папки компонентов с содержанием ниже:

    import _ from 'lodash';    import React, { Component } from 'react';    import { connect } from 'react-redux';    import * as actions from '../actions';    import Item from './item';
        class App extends Component {      state = { item: '' };
          componentWillMount() {        this.props.fetchItems();      }
          handleInputChange(event) {        this.setState({ item: event.target.value });      }
          handleFormSubmit(event) {        event.preventDefault();
            this.props.createItem(this.state.item, Math.floor(Math.random() * 20))      }
          renderItems() {        return _.map(this.props.items, (item, key) => {          return         });      }
          render() {        return (          

    Add Item

      {this.renderItems()}
    ); } }
        function mapStateToProps(state) {      return { items: state.items };    }
        export default connect(mapStateToProps, actions)(App)

    Это умный компонент (или контейнер ), который называет fetchitems () Действие Создатель Как только компонент загружен. Мы также использовали соединить Функция для соединения состояния приложения в Redux к нашему компоненту реагирования. Это достигается с использованием функции MapstatetoProps который принимает в объект дерева Credux State в качестве входного параметра и отображает частью него (элементы) для реквизитов компонента реагирования. Это позволяет нам получить доступ к нему, используя This.props.items Отказ Остальная часть файла позволяет нам принимать пользовательский ввод и добавить его в состояние приложения.

    Запустите приложение, используя NPM начать И попробуйте добавить несколько предметов, как на изображении ниже:

    Резюме

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

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

    Redux делает хорошую работу по четкому определению способа управления вашими данными и как это меняется.

    Он обусловлен тремя основными принципами, которые являются:

    • Единый источник правды для вашего заявления.
    • Состояние только для чтения для обеспечения того, чтобы ни взгляды, ни в результате обратных вызовов сети, не будут писать непосредственно в состояние.
    • И преобразование состояния через чистые функции, называемые редукторами, для предсказуемости и надежности.

    Это делает его предсказуемым состоянием контейнера для приложения JavaScript.

    Дальнейшее чтение

    Исходный код

    Найти исходный код здесь Отказ

    Это было первоначально опубликовано на Толкатель Отказ