На кода-кода мы использовали React + Redux построить несколько проектов. Есть проекты Сделано полностью с redux И есть проекты, где мы использовали Redux вместе с существующим Проект FluxXor Отказ
Redux, кажется, довольно популярен прямо сейчас, поэтому я напишу этот учебник, прежде чем я забуду что-нибудь.
Это первая часть серии RACT & Redux:
- Начало работы с redux: эта статья представит читателей redux на основе того, что я знаю, а также упоминаю, что настолько велико о его дизайне
- Серверный рендеринг App redux : Это руководство проходит как использовать redux и Реагистрационный маршрутизатор Для рендеринга сервера.
- Устройство тестирования приложения redux В этой статье говорится о проблемах, в которых я столкнулся при тестировании кода Redux и как я их решил, а также идут, как сделать ваши устройства тестами со взысканием с помощью погрузчиков WebPack.
Цель этой статьи не учите вас, как создать приложение redux (╯ ° □ °) ╯wait ~ Не закрывайте вкладку Teh ~
К концу чтения этой статьи вы должны иметь лучшее представление о том, как структурировать ваши приложения и как решить проблемы после прочтения Документация Redux Отказ
Что такое redux?
Redux – это каркас, управляющий состояниями в приложении JavaScript. Согласно официальному сайту:
Redux представляет собой предсказуемый государственный контейнер для приложений JavaScript.
В приложении много состояний, которые будут изменяться в зависимости от времени, поведения пользователя или множества разных причин. Таким образом, если мы рассмотрим приложение в качестве процесса для изменения собственного состояния, вид пользователя видит, как представлены состояния.
Например, в приложении «Перепись TODO», когда мы создаем новый элемент TODO, мы фактически изменили состояние приложения из одного без этого товара TODO с элементом TODO. Кроме того, поскольку состояние приложения изменилось, а представление – это то, как представлено государство, мы увидим новый товар TODO на наш взгляд.
Если государство приложения, к сожалению, не ведет себя как ожидалось, то пришло время отлаживать приложение. Например. Если мы добавим новый товар Todo, но наше состояние, по-видимому, добавило два пункта вместо одного, нам придется провести время на выяснение, какое изменение состояния пошло не так. Звучит довольно просто на бумаге, верно? Если вы думаете, что этот процесс будет легким, ты слишком наивный …. Приложения Real-World часто являются гораздо более сложными, и существует множество факторов, которые сделают эту отладочную обработку кошмаром, например, иметь плохую привычку кодирования, недостатки в рамках дизайна, не вкладывая время в письменных модулях и т. Д.
Рамка Redux предназначена для облегчения процесса отладки. Быть более конкретным, redux – это каркас, который расширяет идеи Flux и упрощает избыточные вещи. Как это ставит его на официальный сайт:
Redux развивает идеи поток, но избегает его сложности, принимая сигналы от Elm Отказ
Что было не так с оригинальными каркасами MVC?
Первоначально было много MVC Frameworks из разных размеров и форм, но обычно можно либо классифицировать как MVC S или расширение MVC.
Flux/redux пытается решить проблему, в которой ошибки трудно проследить, когда модель непрерывно обновляется, поскольку приложение используется.
Так же, как показано в следующий график :
Как видно на изображении, любой данный вид может повлиять на любую модель и наоборот. Проблема с этим, когда есть много просмотров и моделей, и одно из состояний модели изменилось в то, что мы не ожидали, мы не можем эффективно следить, и какую модель вызвало проблему Также слишком много возможностей.
Flux/redux облегчает отладку приложений для отладки, удалив установку модели (магазина AKA), а затем позволить магазину обновлять свое собственное состояние через Действие
(который является «поток данных» « в однонаправлении », упомянутые на официальном сайте React.) Кроме того, отправка Действие
не может отправить другой Действие
Отказ Таким образом, магазин будет активно обновляться в отличие от пассивно обновления, и всякий раз, когда есть ошибка, мы можем обратиться к проблемному магазину, чтобы увидеть, какие события произошли раньше. Это облегчает ошибку охотиться, так как мы по сути обольнули возможности, которые вызвали ошибку.
Как работает redux?
Redux можно разбиться в следующее:
магазин
Управляет государствами. В основном естьОтправка
Метод отправкиДействие
Отказ В приложении Redux вы можете получить его состояния черезStore.getState ()
Действие
: простой, простой объект JavaScript. Действие также может рассматриваться как команда для изменения состояния.Редуктор
: решает, как изменить состояние после полученияДействие
И, таким образом, можно считать вход в изменение состояния. АРедуктор
состоит из функций, и он меняет состояния, принимаяДействие
как аргумент, в котором это тогдаВозвращение
с новым государством.промежуточное программное обеспечение
: посредник междуstore.dispatch ()
и аРедуктор
Отказ Его цель – перехватитьДействие
это былоОтправка
изменить или даже отменитьДействие
до того, как он достигнетРедуктор
Отказ
Как показано выше, если мы добавили новый элемент TODO в приложении Redux, мы сначала создам Действие
с типом Add_todo
, а затем отправьте действие через store.dispatch ()
Отказ
// actionCreator export function addTodo(text) { return { type: types.ADD_TODO, text }; } store.dispatch(addTodo({ text: 'Clean bedroom' });
Впоследствии это Действие
войдет в промежуточное программное обеспечение
и, наконец, войти в Редуктор
Отказ Внутри Редуктор
Состояние будет изменяться соответственно к типу действия.
// reducer function todos(state, action) { switch(action.type) { case 'ADD_TODO': // handle action and return new state here } }
Итак, мы завершили самое основное поведение обновления государства.
В более сложном приложении нам нужно будет разделить состояние магазина на разных частях, подобных, как мы сделаем, когда имен. Вы можете сделать это в Redux, создав разные редукторы для управления различными областями состояния, а затем объединить их вместе через Коммунатории
Отказ
Процесс должен выглядеть так:
Async & Mardware
Мы уже ввели обновление государства, но приложение для интерфейса никогда не бывает так просто …
Здесь мы перейдем, как обрабатывать асинхронное поведение в приложении redux. В этом разделе мы рассмотрим процесс отправки HTTP-запроса, чтобы понять, как Async работает в Redux.
Образец ситуации
Допустим, у нас есть приложение, которое называется список вопросы
Отказ В какой-то момент (например, пользователь нажимает кнопку), нам нужно будет отправить запрос на наш сервер, чтобы получить данные в вопросы
Отказ Отправляя этот запрос, нам нужно отразить Отправка
Состояние в нашем магазине, и если запрос был успешно успешно, нам нужно будет поставить данные вопросы
в нашем магазине. Если запрос HTTP не удался, нам нужно будет отражать информацию о выступлении в нашем магазине.
Простое решение
Один наивный способ приблизиться к этой ситуации – Отправка
разные события в разное время. В следующем ниже я использовал SuperaGent сделать мои просьбы.
import request from 'superagent'; const SENDING_QUESTIONS = 'SENDING_QUESTIONS'; const LOAD_QUESTIONS_SUCCESS = 'LOAD_QUESTIONS_SUCCESS'; const LOAD_QUESTIONS_FAILED = 'LOAD_QUESTIONS_FAILED'; store.dispatch({ type: SENDING_QUESTIONS }); request.get('/questions') .end((err, res)=> { if (err) { store.dispatch({ type: LOAD_QUESTIONS_FAILED, error: err }); } else { store.dispatch({ type: LOAD_QUESTIONS_SUCCESS, questions: res.response }); } });
Таким образом, мы можем достичь асинхронизации в приложении Redux. Однако этот подход не подходит, если мы должны отправить много HTTP-запросов, поскольку нам нужно добавить асинхронное поведение на каждый запрос, и это затрудняет сохранение нашего кода. Кроме того, этот подход также не прост в тесте, тем более что асинхронный код сложнее понять и тестировать в целом. Наконец, если мы будем использовать этот подход в приложении React App, мы будем вынуждены кодировать эту логику в компоненте реагирования.
Наиболее идеальным способом решить эту проблему является извлечение и собрать все подобное асинхронное поведение в том же месте, и вот где промежуточное программное обеспечение
приходит в!
Что такое промежуточное программное обеспечение?
Как указано ранее, в Redux промежуточное программное обеспечение похоже на переговорщик между Store.Dispatch
и Редуктор
Отказ Быть более конкретным, store.dispatch ()
Мы называем на самом деле состоит из слоев промежуточного программного обеспечения, а редуктор находится на внутреннем слое.
Мы можем визуализировать это через следующее изображение:
Через промежуточное программное обеспечение мы можем извлечь вышеупомянутый асинхронный запрос API и поместите их в одинаковое промежуточное программное обеспечение. Другими словами, при отправке запроса API нам понадобится Отправка
Действие
определенного типа, а затем позвольте наше промежуточное программное обеспечение перехватывает такие типы Действие
с для отправки соответствующего запроса API.
Вот что может выглядеть наше промежуточное программирование:
// middlewares/api.js import superAgent from 'superagent'; export const CALL_API = Symbol('CALL_API'); export default store => next => action => { if ( ! action[CALL_API] ) { return next(action); } let request = action[CALL_API]; let { method, path, query, failureType, successType, sendingType } = request; let { dispatch } = store; dispatch({ type: sendingType }); superAgent[method](path) .query(query) .end((err, res)=> { if (err) { dispatch({ type: failureType, response: err }); } else { dispatch({ type: successType, response: res.body }); } }); };
В указанном выше коде промежуточное программное обеспечение будет перехватывать любой Действие
с Call_api
ключ, а затем отправьте запрос API на основе Метод
, путь
, Запрос
, Uscesstype
и т.д. хранится внутри Действие
Отказ
Таким образом, когда нам действительно нужно отправить запрос, нам не придется иметь дело с асинхронной логикой, и нам нужно только Отправка
Действие
что имеет Call_api
Отказ
import { CALL_API} from 'middlewares/api'; const SENDING_QUESTIONS = 'SENDING_QUESTIONS'; const LOAD_QUESTIONS_SUCCESS = 'LOAD_QUESTIONS_SUCCESS'; const LOAD_QUESTIONS_FAILED = 'LOAD_QUESTIONS_FAILED'; store.dispatch({ [CALL_API]: { method: 'get', path: '/questions', sendingType: SENDING_QUESTIONS, successType: LOAD_QUESTION_SUCCESS, failureType: LOAD_QUESTION_FAILED } });
Сгруппируя асинхронное поведение в промежуточном программе, мы устраняем необходимость написания дубликатовной логики в нашем коде. Мы также делаем тестирование проще, так как тот факт, что «диспетчерничество действие
с Call_api
теперь синхронное поведение, и мы в конечном итоге избегаем необходимости проверять Async Code.
Дизайн промежуточного программного обеспечения Redux является одной из главных причин, по которой я нахожу каркас элегантный. Через промежуточное программное обеспечение мы можем извлечь избыточную логику, такую как запрос API, упомянутый выше, и мы также можем Журнал всевозможные поведения. Я думаю, что концепция этого дизайна близка к Цепочка ответственности Узор Отказ Другие подобные понятия появились в Express.js промежуточное ПО и Стойка промежуточного программного обеспечения Отказ
Держись, как насчет реагирования?
Прочитав эссе, объясняющий, что делает redux, вы можете понять, что ничего не было сказано о реагировании.
Да, реагируют и redux не имеют прямых отношений – Redux управляет изменением состояния приложения, в то время как React оказывает представление состояний.
Сила реагирования – это его виртуальный DOM для эффективного повторного визуализации представления, когда состояние было изменено на новое состояние (которое упаковано в реквизит
). Другими словами, разработчик приложений не должен управлять, какая часть измененного состояния была изменена и просто позвольте реагировать на него.
Так как вы используете React & Redux вместе? Мы делаем это, найдя компоненты реагирования верхнего уровня, а внутри этих компонентов мы установим состояние Redux в качестве состояния компонента. Когда эти состояния меняются, мы будем использовать нашу удобство SetState
Компонент для запуска рендеринга. Таким образом, React и Redux States будут связаны вместе.
После того, как у нас есть эти компоненты «верхнего уровня», мы можем сломать их на еще более мелкие компоненты, проходящие штаты Redux, как React реквизит
Создать подсомысенные компоненты. Тем не менее, Эти подтекаторы не связаны напрямую для Redux, потому что их поведение полностью определяется реквизит
Отказ Или нет ?| опора Пришел из Redux не имеет значения для этих подсомов.
На самом деле, «компоненты верхнего уровня», которые я упомянул, официально называется Умные компоненты В redux и «подтенеры» называются Тупые компоненты Отказ соединить
Функция в React-redux крючков соединяет состояния redux и умные компоненты.
Как выглядит ract + redux?
Приведенный ниже пример от официального примера TodyVC сайта redux, а точка входа index.js
Похоже, это выглядит:
import 'babel-core/polyfill'; import React from 'react'; import { render } from 'react-dom'; import { Provider } from 'react-redux'; import App from './containers/App'; import configureStore from './store/configureStore'; import 'todomvc-app-css/index.css'; const store = configureStore(); render(, document.getElementById('root') );
В вышеуказанном коде мы можем увидеть компонент приложения Приложение
обернут внутри Провайдер
Компонент, и это Провайдер
Компонент использует опора
Чтобы указать нам в состояние приложения: магазин
Отказ
Вот что наше Приложение
Компонент Контейнеры/App.js
должен выглядеть как:
import React, { Component, PropTypes } from 'react'; import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import Header from '../components/Header'; import MainSection from '../components/MainSection'; import * as TodoActions from '../actions/todos'; class App extends Component { render() { const { todos, actions } = this.props; return (); } } App.propTypes = { todos: PropTypes.array.isRequired, actions: PropTypes.object.isRequired }; function mapStateToProps(state) { return { todos: state.todos }; } function mapDispatchToProps(dispatch) { return { actions: bindActionCreators(TodoActions, dispatch) }; } export default connect( mapStateToProps, mapDispatchToProps )(App);
Здесь мы увидим это Приложение
На самом деле просто простой реактивный компонент и, похоже, имеет мало, чтобы сделать с redux. Однако в конце концов .js Файл не Экспорт
Приложение
Компонент напрямую, но экспортирует возвращенный результат соединить
Отказ Помните, соединить
Функция будет интегрировать Redux в нашу Приложение
составная часть.
На соединить
Этап, мы пройдем MapstatetoProps
и mapdispatchtopops
в соединить
Отказ
Прежде всего, MapstatetoProps
Фильтрует результаты Redux States (Store.getState ()) во что-то, что нуждается в интеллектуальном компонентах, а затем передает их в компонент в виде опора
Отказ На основе образца выше, MapstatetoProps
должен вернуться:
{ todos: state.todos };
Поэтому мы должны использовать Это.props.todos
чтобы получить Хранить, getstate (). ToDos
от Приложение
Компонент, который был соединить
ред.
Во-вторых, mapdispatchtopops
принимает набор акций создателей (которые просто возвращают Action
объекты) и сделать их «диспетчером». Затем он передает объект к компонентам как опора
Отказ
В образце выше, Todoactions.adtodo
это объект, который просто возвращает Действие
:
// actions/todos.js export function addTodo(text) { return { type: types.ADD_TODO, text }; }
Однако через соединить
Функция, наш Приложение
Компонент получит this.proops.action.addtodo
и эта функция Отправка
ES Оригинальный Ection Creator, который был возвращен Действие
Объект, то есть.:
dispatch(ActionCreators.addTodo(...))
Как делает соединять получить хранить ?
После изучения Контейнеры/App.js
выше, вы, вероятно, поймете, что магазин
Не появляется где угодно в коде!
Вы можете задуматься, как соединить
получает магазин
Когда он подключает компонент реагирования к состоянию Redux.
Ответ: соединить
Получает магазин
через Провайдер
Вы видели в index.js
Отказ
В index.js
мы прошли магазин
в нашу Провайдер
как опора
и Провайдер
Установит магазин
в качестве собственного реагирования контекст
*. Таким образом, все детские компоненты Провайдер
может получить магазин
через контекст
Отказ Таким образом, Приложение
это было соединить
Эд также может получить магазин
через контекст
Отказ
Заключение
Лично я думаю, что redux имеет много элегантно оформленных функций и по сравнению с FluxXor Вы можете написать намного менее повторяющийся код и логику.
Из всех функций я люблю redux’s промежуточное программное обеспечение
большинство. После прочтения исходного кода для промежуточного программного обеспечения я понял, что в коде есть много функциональных концепций программирования. Я не знаком с функциональным программированием, поэтому это открыло мои глаза на новую перспективу и позволило мне понять JavaScript с пресной точки зрения.
Кроме того, я думаю, что это было отличное решение извлечения части, которая соединяет реакцию и Redux в библиотеку, так как этот способ Redux не будет напрямую связан с реакцией.
С точки зрения тестирования, любой тест, который предполагает представления, обычно довольно сложны, но Redux облегчает облегчение компонентов «тупой». «Тупые» компоненты только зависят от реквизит
И, таким образом, можно легко проверить.
* Примечание: Перед реагированием 0,13, контекст
был владелец -на основе. После реагирования 0,14 они все были изменены на родительский. Это также почему в React 0.13 и более ранние версии мы обычно должны обернуть функцию вокруг Приложение
в нашем Провайдер
С тех пор это не позволит Ошибка . где на основе родительских и на основе владельцев контексты различались.
{ ()=> { } }
Этот пост был первоначально опубликован на китайском здесь и был переведен на английский по команде контента кодаментатора. Не стесняйтесь оставить комментарий ниже, если у вас есть какие-либо отзывы или вопросы!