Разное

Redux на русском документация: Памятка · Redux documentation in russian

Содержание

Памятка · Redux documentation in russian

  • Redux documentation in russian
  • Содержание
  • Памятка

  • Введение

    • Мотивация

    • Базовые концепции

    • Три принципа

    • Предшественники

    • Образовательные ресурсы

    • Экосистема

    • Примеры

  • Основы

    • Экшены

    • Редюсеры

    • Стор

    • Поток данных

    • Использование с React

    • Пример: Todo List

Текстовый туториал по React.js и Redux на русском / Хабр

(у учебника по Основам React вышло второе издание, Redux-учебник в процессе обновления)


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

Курс про Redux попал в официальную документацию.

Оба руководства бесплатны и выложены на gitbook (можно скачать PDF, ePub, mobi).

В текстах нарочно участвуют термины переведенные на русский (например, состояние), английские (state), либо английский термин написанный по-русски — стейт. Считаю это допустимым, и даже более того, удобным для читателя.

React.js для начинающих

В данном курсе затронуты основы «реакта». Результатом будет небольшое приложение, в котором пользователь сможет добавить новость в ленту новостей.

Здесь специально не рассматривается webpack, hot module replacement и так далее. Реакт — это библиотека, значит достаточно просто добавить скрипт на страницу и начать писать на нем.

Чуть подробнее чем остальные темы, в курсе разобрана работа с формой (контролируемые и неконтролируемые компоненты). Остальные разделы — минимум текста. Не забыты propTypes.

В заключении курса (на данный момент) рассматривается простая реализация системы глобальных событий. Что плавно подводит читателя к тому, почему flux (и Redux) были созданы.

В планах написать об анимациях.

Код — ES5. Прямая ссылка на курс (PDF, ePub, mobi).

Redux

В данном курсе наоборот, добавлены webpack и поддержка HMR, разработка становится более комфортной, но, возможно, несколько запутанной на стадии подготовки, если читатель никогда не работал с webpack и babel.

Результатом будет мини-приложение, которое позволить получить фото из VK за разные года, отсортированное по «лайкам». Освещены запросы выполнения ajax-запросов в частности и «как вообще это работает», если вы решили использовать Redux подход.

Для тех, кто только выбирает flux-архитектуру, или вообще еще не работал с react, хочу сказать, что redux подход мне очень симпатизирует. На мой взгляд он хорошо структурирует код и делает его читаемым. Даже если вы откроете «слегка подзабытый» проект, то вам не потребуется много времени на то, чтобы вспомнить что и как работает.

В планах — роутинг, оптимизация сборки.

Код — ES2015/ES7. Прямая ссылка на курс (PDF, ePub, mobi).

В качестве заключения

Буду рад услышать критику по тексту, по коду и вообще. Какие главы плохо написаны (если вы «бывалый»), либо какие главы вам были не понятны (если вы «начинающий»)?

Какие вопросы были не затронуты в туториалах, но на которые вы жаждите узнать ответ?

Спасибо за внимание.

Введение · Redux documentation in russian

  • Redux documentation in russian
  • Содержание
  • Памятка

  • Введение

    • Мотивация

    • Базовые концепции

    • Три принципа

    • Предшественники

    • Образовательные ресурсы

    • Экосистема

    • Примеры

  • Основы

    • Экшены

    • Редюсеры

    • Стор

    • Поток данных

    • Использование с React

    • Пример: Todo List

  • Продвинутое использование

    • Асинхронные экшены

    • Асинхронные потоки

    • Мидлвар

    • Использование с React Router

    • Пример: Reddit API

    • Следующие шаги

  • Рецепты

    • Мигрирование на Redux

    • Использование оператора расширения

    • Упрощение шаблона

    • Серверный рендеринг

    • Написание тестов

    • Оперирование полученными данными

    • Реализация истории отмен

    • Изолирование саб-приложений

Знакомимся с Redux: основные принципы JavaScript-библиотеки

Знакомимся с Redux на понятном языке. Минимальные требования для изучения − знание React. В этом материале разбираем принципы библиотеки.

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

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

Также проверка показала, что даже сертифицированный курс разработки React (который стоил в США больше 300 долларов) не помогает новичкам разобраться в полной мере.

Ну что, знакомимся с Redux на понятном языке?

Если вы когда-нибудь пробовали вникать в тему, то знаете, что Redux − ничто, по сравнению со связанными библиотеками, которые тоже следует знать: React-Redux, Redux-thunk, Redux-сага, Redux-обещание, Reselect, Recompose и куча других. У каждой из них свои особенности. Но в нашей статье представлен только базис, который позволит разобраться дальше самим. Не нужно сразу грузить себя сложными вещами.

Единственное, что вы уже должны знать к началу изучения темы − React. Если таких знаний пока нет, то хотя бы прочтите Pure React.

Несколько лет назад разработка интерфейсных приложений казалась чем-то несерьёзным. Теперь от таких приложений требуют большего, поэтому сложность разработки возросла. Это сравнимо с ситуацией, когда кот больше не помещается в обычную коробку, и теперь нужно сделать для него новое место жительства, а это требует больше усилий. Хотя все процессы так устроены: чем дальше и больше, тем сложнее.

Что такое Redux

Согласно документации, Redux − это предсказуемый контейнер состояния для JavaScript-приложений. Да, это звучит странно и непонятно. На самом деле суть Redux в том, чтобы приручить того самого кота из коробки, а точнее сделать так, чтобы приложения работали последовательно. Кроме этого, у него есть много других преимуществ, но об этом позже.

Зачем использовать Redux

Да, обычно сложно убедить кого-то использовать инструмент A вместо инструмента B, если они похожи. Каждый выбирает то, что ему больше нравится. Так и с Redux: разработчики и без него чувствуют себя нормально, на ранних этапах это точно не стоит траты времени.

Но когда приложение становится нагруженным, тогда стоит внедрить Redux в целях повышения производительности. А ещё Redux любят за то, что можно быстро изучить основы и выйти на рынок труда. Или за то, что здесь есть функции logging, hot reloading, time travel, universal apps, record и replay. Изучите, как они работают с помощью лекции.

Плюс статистика: 60% React-приложений используют Redux. В этом материале собрано ещё больше аргументов в пользу изучения Redux. Да и в конце концов, когда знания были лишними?

Как это работает в глазах пятилетнего ребёнка или разбираем принципы

Так как мы только знакомимся с Redux, ситуативные примеры тоже полезны. Допустим, вы идёте в банк снимать деньги. У вас есть единственная цель − снять деньги, а не что-то ещё. Вот она − WITHDRAW_MONEY.

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

Но в жизни, как и в Redux, это работает по-другому. Комната, где хранятся деньги, − это Redux Store, а state − часть денег в хранилище, которая принадлежит вам. Ваши Redux-приложения тоже хранятся в общем Redux Store. И это первый принцип Redux.

Состояние всего вашего приложения сохранено в дереве объектов внутри одного хранилища

Идя в банк, вы думаете о том, чтобы произвести какое-то действие − action. Если вы собираетесь снять деньги, то action − снятие денег. То же самое применимо к Redux. Напишите сколько угодно кода, но если вы захотите обновить состояние своего приложения Redux (как setState в React), вам нужно сообщить Redux об этом с помощью action.

Redux как гарант того, что с вашим счётом ничего незаконного не случится, потому что он постоянно проверяет состояние банковского счёта. Это второй принцип Redux.

Единственный способ изменить состояние − это применить действие − объект, который описывает, что случится

Кассир для банка − как reducer для Redux. В истории выше нужно было обязательно встретиться с кассиром, который имеет доступ к деньгам. То же самое с Redux: вам обязательно нужно сообщить, что вы хотите сделать. Если вы хотите обновить состояние вашего приложения, вы передадите ваш action в reducer. Вообще, это называется диспетчеризация.

reducer знает, что ему нужно делать. В этом примере он предпримет действие WITHDRAW_MONEY и обеспечит получение денег. В условиях Redux деньги, которые вы тратите, находятся в state. Когда reducer узнает что нужно что-то сделать, он вернёт вас в позицию new state.

Для определения того, как дерево состояния будет трансформировано действиями, вы пишете чистые редюсеры

Отлично, теперь вы знаете основы Redux и то, как работают store, reducer и action.

Смотрите также нашу статью о первом приложении на Redux.

Redux. Простой как грабли / Хабр

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

TL;DR: базовая логика redux помещается в 7 строк JS кода.

О redux вкратце (вольный перевод заголовка на гитхабе):

Redux — библиотека управления состоянием для приложений, написанных на JavaScript.

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

Я склонировал репозиторий redux, открыл в редакторе папку с исходниками (игнорируя docs, examples и прочее) и взялся за ножницы клавишу Delete:

  • Удалил все комментарии из кода

    Каждый метод библиотеки задокументирован с помощью JSDoc весьма подробно
  • Убрал валидацию и логирование ошибок

    В каждом методе жёстко контролируются входные параметры с выведением очень приятных глазу подробных комментариев в консоль
  • Убрал методы bindActionCreators, subscribe, replaceReducer и observable.

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

А теперь давайте разберём то, что осталось


Пишем redux за 7 строк

Весь базовый функционал redux умещается в малюсенький файлик, ради которого вряд ли кто-нибудь будет создавать github репозиторий 🙂

function createStore(reducer, initialState) {
    let state = initialState
    return {
        dispatch: action => { state = reducer(state, action) },
        getState: () => state,
    }
}

Всё. Да, серьёзно, ВСЁ.

Так устроен redux. 18 страниц вакансий на HeadHunter с поисковым запросом «redux» — люди, которые надеются, что вы разберетесь в 7 строках кода. Всё остальное — синтаксический сахар.

С этими 7 строками уже можно писать TodoApp. Или что угодно. Но мы быстренько перепишем TodoApp из документации к redux.

// Инициализация хранилища
function todosReducer(state, action) {
  switch (action.type) {
    case 'ADD_TODO':
      return [
        ...state,
        {
          id: action.id,
          text: action.text,
          completed: false
        }
      ]
    case 'TOGGLE_TODO':
      return state.map(todo => {
        if (todo.id === action.id) {
          return { ...todo, completed: !todo.completed }
        }
        return todo
      })
    default:
      return state
  }
}

const initialTodos = []

const store = createStore(todosReducer, initialTodos)

// Использование
store.dispatch({
  type: 'ADD_TODO',
  id: 1,
  text: 'Понять насколько redux прост'
})

store.getState() 
// [{ id: 1, text: 'Понять насколько redux прост', completed: false }]

store.dispatch({
  type: 'TOGGLE_TODO',
  id: 1
})

store.getState() 
// [{ id: 1, text: 'Понять насколько redux прост', completed: true }]

Уже на этом этапе я думал бросить микрофон со сцены и уйти, но show must go on.
Давайте посмотрим, как устроен метод.

combineReducers

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

Используется он так:

// здесь мы переиспользуем метод todosReducer из прошлого примера

function counterReducer(state, action) {
  if (action.type === 'ADD') {
    return state + 1
  } else {
    return state
  }
}

const reducer = combineReducers({
  todoState: todoReducer,
  counterState: counterReducer
})

const initialState = {
  todoState: [],
  counterState: 0,
}

const store = createStore(reducer, initialState)

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

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

В документации используют модный синтаксис из ES6 (7/8/∞):

const reducer = combineReducers({ todos, counter })

и соответственно переименовывают todoReducer в todos и counterReducer в counter. И многие в своём коде делают то же самое. В итоге разницы нет, но для человека, знакомящегося с redux, с первого раза эта штука выглядит магией, потому что ключ части состояния (state.todos) соответствует функции, названной также только по желанию разработчика (function todos(){}).

Если бы нам нужно было написать такой функционал на нашем micro-redux, мы бы сделали так:

function reducer(state, action) {
  return {
    todoState: todoReducer(state, action),
    counterState: counterReducer(state, action),
  }
}

Этот код плохо масштабируется. Если у нас 2 «под-состояния», нам нужно дважды написать (state, action), а хорошие программисты так не делают, правда?

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

Однако реализация метода combineReducers довольно простая (напоминаю, это если убрать валидацию и вывод ошибок) и самую малость отрефакторить на свой вкус:

function combineReducers(reducersMap) {
  return function combinationReducer(state, action) {
    const nextState = {}
    Object.entries(reducersMap).forEach(([key, reducer]) => {
      nextState[key] = reducer(state[key], action)
    })
    return nextState
  }
}

Мы добавили к нашему детёнышу redux ещё 9 строк и массу удобства.

Перейдём к ещё одной важной фиче, которая кажется слишком сложной, чтобы пройти мимо неё.

applyMiddleware

middleware в разрезе redux — это какая-то штука, которая слушает все dispatch и при определенных условиях делает что-то. Логирует, проигрывает звуки, делает запросы к серверу,… — что-то.

В оригинальном коде middleware передаются как дополнительные параметры в createStore, но если не жалеть лишнюю строчку кода, то использование этого функционала выглядит так:

const createStoreWithMiddleware = applyMiddleware(someMiddleware)(createStore)
const store = createStoreWithMiddleware(reducer, initialState)

При этом реализация метода applyMiddleware, когда ты потратишь 10 минут на ковыряние в чужом коде, сводится к очень простой вещи: createStore возвращает объект с полем «dispatch». dispatch, как мы помним (не помним) из первого листинга кода, — это функция, которая всего лишь применяет редюсер к нашему текущему состоянию (newState = reducer(state, action)).
Так вот applyMiddleware не более чем переопределяет метод dispatch, добавляя перед (или после) обновлением состояния какую-то пользовательскую логику.

Возьмём, например, самый популярный middleware от создателей redux — redux-thunk

Его смысл сводится к тому, что можно делать не только

store.dispatch({type: 'SOME_ACTION_TYPE', some_useful_data: 1 })

но и передавать в store.dispatch сложные функции

function someStrangeAction() {
  return async function(dispatch, getState) {
    if(getState().counterState % 2) {
       dispatch({
         type: 'ADD',
       })
    }
    await new Promise(resolve => setTimeout(resolve, 1000))
    dispatch({
      type: 'TOGGLE_TODO',
      id: 1
    })
  }
}

И теперь, когда мы выполним команду

dispatch(someStrangeAction())

то:

  • если значение store.getState().counterState не делится на 2, оно увеличится на 1
  • через секунду после вызова нашего метода, todo с id=1 переключит completed true на false или наоборот.

Итак, я залез в репозиторий redux-thunk, и сделал то же самое что и с redux — удалил комментарии и параметры, которые расширяют базовый функционал, но не изменяют основной

Получилось следующее:

const thunk = store => dispatch => action => {
  if (typeof action === 'function') {
    return action(store.dispatch, store.getState)
  }
  return dispatch(action)
}

я понимаю, что конструкция

const thunk = store => dispatch => action

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

Напомню, оригинальный метод createStore выглядел так

function createStore(reducer, initialState) {
    let state = initialState
    return {
        dispatch: action => { state = reducer(state, action) },
        getState: () => state,
    }
}

То есть он принимал атрибуты (reducer, initialState) и возвращал объект с ключами { dispatch, getState }.

Оказалось, что реализовать метод applyMiddleware проще, чем понять, как он работает.

Мы берём уже реализованный метод createStore и переопределяем его возвращаемое значение:

function applyMiddleware(middleware) {
  return function createStoreWithMiddleware(createStore) {
    return (reducer, state) => {
      const store = createStore(reducer, state)

      return {
        dispatch: action => middleware(store)(store.dispatch)(action),
        getState: store.getState,
      }
    }
  }
}

Вывод

Под капотом redux содержатся очень простые логические операции. Операции на уровне «Если бензин в цилиндре загорается, давление увеличивается». А вот то, сможете ли вы построить на этих понятиях болид Формулы 1 — уже решайте сами.

P.S.

Для добавления в мой «micro-redux» упрощённого метода store.subscribe потребовалось 8 строк кода. А вам?

Текстовый туториал по react-router, а так же react-router + redux. На русском / Хабр

Всем добрый день. Немного с задержкой, но все же выходит третий мини-учебник. На этот раз разобран react-router. А так же две главы посвещены интеграции react-router + redux.

В процессе интеграции rr+redux я не использовал react-router-redux и redux-router. Как указано в самой книге, из-за активного развития библиотек, мне хотелось бы «научить вас рыбачить», а не просто «дать рыбу».

Также, приведенный способ по интеграции основан на личном опыте, плюс ответах разработчика redux (его твиттер) на SO, и изучении различных репозиториев. Он не является «единственно верным». Пожалуйста, укажите ссылки на ваши репозитории, либо предложите свои варианты в комментариях.

Поехали!

React-router

Библиотека в рекламе не нуждается. Мощные возможности по вложению роутов (nesting) и в принципе, хорошая высокоуровневая абстракция.

В основе материала – официальные туториалы (раз, два), а так же несколько блогов (например, блог James K Nelson’a).

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

React-router + redux

Многие (как и я) ждут этого раздела в официальной документации redux. Но пока этого не случилось, на помощь приходит «философия redux» + крупицы информации разбросанные по сети.

Что я имею ввиду под «философией redux»?

Во-первых: роутинг – это «действия» (actions).

Во-вторых: мы не можем просто взять и использовать browserHistory.push внутри уже существующих actionCreators (функций-создателей действий). Почему? Потому что – это side-эффект.

На помощь приходит идея использования middleware’ов (функций-прослоек). Например, хочется использовать примитивный вариант:

Если action.redirect есть -> browserHistory.push(nextUrl)*

Данный ответ нарушает соглашение, что middleware обязан возвращать next().

* я уже второй раз упоминаю browserHistory. Это связано с тем, что данные методы (push, replace, и т.д.) доступны по умолчанию, когда вы подключаете на проект react-router.

В поисках ответа на вопрос, я посмотрел глубже в код redux-router. Я хотел достичь следующей цели: иметь возможность вызывать роутинг с помощью нативного для redux – store.dispatch

Таким образом мы сохраняем «философию». Весь процесс «потока данных» в приложении четко контролируется нами.

В туториале разобрана банальная задача:

Если пользователь ввел логин – перенаправь его на /admin, если же пользователь не залогинен и пытается зайти на /admin – перекинь его на форму регистрации ( /login ).

Для успешного решения этой задачи я использовал код react-redux-jwt-auth-example. Отличная демонстрация мощного приема «оборачивания компонента».

Решение этой задачи и есть ключ к пониманию процесса вызова действий, связанных с роутингом, так как все задачи «оперы» redux + роутинг сводятся к следующему: получен какой-то ответ (success, failure…) — отправь (dispatch) событие роутинга.


Вопрос к хабражителям:

Как думаете, нужно ли сделать отдельную статью для описания процесса интеграции react-router + redux (по факту это раздел «Подключаем redux» из учебника. Он короткий)? Для чего? Возможно, другие разработчики, кто давно работает с такой связкой увидят подход и код сразу в статье, а следовательно, прокомментируют.

Внизу опрос.


Интересные вопросы на SO:

You don’t have to keep everything in the store

Transition to another route on successful async redux action

How to connect to redux store from react-router onEnter hook?


Немного статистики (на 25.04.2016):

React.js для начинающих: 59,481 просмотров, 8,245 посетителей, 3,843 скачиваний в формате pdf/epub/mobi.

Туториал по Redux на русском: 66,978 просмотров, 7,942 посетителей, 2,832 скачиваний.

На оба курса – 41 + 38 «дискуссий». Это в основном грамматические ошибки. Есть так же пара дельных замечаний (на хабре).

Я хочу сказать всем большое спасибо за ваше участие и интерес. По-прежнему на связи: twitter, почта — [email protected]

P.S. автор обложки [email protected] (Мария, профиль на freelance)

Совершенствуем Redux / Хабр

Привет, Хабр! Представляю вашему вниманию перевод статьи «Redesigning Redux» автора Shawn McKay.

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

  • Вам действительно необходима библиотека для управления состоянием?
  • Заслужил ли Redux свою популярность? Почему или почему нет?
  • Можем ли мы придумать лучшее решение? Если да, то какое?

Необходима ли библиотека для управления состоянием?

Front-end разработчик не тот, кто попросту передвигает пиксели из стороны в сторону; истинное искусство в знании где хранить состояние. Это кажется сложным только на первый взгляд.

Давайте рассмотрим возможности, которые предоставляет нам React:

1. Состояние компонента (Component State)

Состояние хранится внутри компонента. В React мы обновляем state через setState().

2. Относительное состояние (Relative State)

Состояние переданное от родителя потомку. В React передаем props как свойство компонента потомка.

3. Переданное состояние (Provided State)

Состояние хранится в поставщике (provider), и доступно любому компоненту (consumer), расположенному ниже по дереву. Context API в React.

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

Размещение всего кода внутри компонентов может привести к низкому разделению ответственности: растет зависимость от view-библиотек, усложняется тестирование такого кода, но самое страшное: приходится регулярно менять способ хранения состояния.

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

4. Внешнее состояние (External State)

Состояние может находиться отдельно от компонентов, которые синхронно «свяжуться» с ним при помощи provider/consumer паттерна. Вероятнее всего самой большой популярностью, среди библиотек для управления состоянием, пользуется Redux. В течении последних двух лет она получила большую известность среди разработчиков. Так в чем причина такой любви к одной библиотеке?

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

Redux прост в применении? Конечно нет.

Простым был бы нативный javascript:

Так почему каждый не может использовать global.state = {}?

Почему Redux?

Под капотом, Redux аналогичен глобальному объекту TJ, только обернут рядом утилит.

В Redux можно непосредственно изменять состояние, путем передачи (dispatch) действий (action) через указанные инструменты.

Библиотека включает два вида обработчиков действий: middleware & subscriptions. Middleware — это функции, которые перехватывают действия. Включают такие инструменты как «logger», «devtools» или «syncWithServer». Subscriptions — это функции, используемые для отправки изменений компонентам.

Наконец, редьюсеры (reducer) — это функции, которые изменяют состояние и делят его на мелкие, модульные и управляемые части.

Вероятнее всего, Redux более применим для хранения состояния, чем глобальный объект.

Думайте о Redux как о глобальном объекте с расширенными возможностями и упрощенным способом «преобразования» состояния.

Настолько ли сложен Redux?

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

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

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

Вы не должны разбираться что такое «comonad», используя jQuery, и не обязаны понимать функциональную композицию, чтобы справиться с управлением состоянием.

Цель любой библиотеки: сделать сложное простым при помощи абстракции.

Я не намерен высмеивать Дэна Абрамова. Redux стал популярным на слишком ранней стадии своего развития.

  • Как внести изменения в библиотеку, которую используют миллионы разработчиков?
  • Как вы оправдаете критические изменения, которые повлияют на проекты во всем мире?

Вы не сможете. Но предоставив расширенную документацию, обучающие видео и помощь комьюнити, вы окажете неоценимую помощь. У Дэна Абрамова получилось это.

А может есть другой путь?

Совершенствуем Redux

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

1. Настройка

Предлагаю посмотреть на первоначальную настройку Redux-приложения (левый скрин).

Много разработчиков, сразу после первого шага, остановились в недоумении. Что такое thunk? compose? Способна ли функция на такое?

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

2. Упрощаем редьюсеры

Редьюсеры в Redux могут использовать switch-конструкции далекие от тех, которые мы привыкли использовать.

Учитывая, что редьюсеры находят соответствие по типу действия, мы можем сделать каждый редьюсер чистой (pure) функцией, принимающей состояние и действие. Можно сократить действие и передавать только состояние и данные.

3. Async/Await без Thunk

Thunk широко используется для создания асинхронных действий в Redux. Во многих отношениях, thunk больше похож на умный хак, чем на официально рекомендуемое решение. Как это работает:

  1. Вы передаете действие, уже как функцию, а не объект.
  2. Thunk проверяет каждое действие, что оно является функцией.
  3. Если все сходится, thunk вызывает эту функцию и передает в нее некоторые методы стора: dispatch и getState.

Серьезно? Следует ли таким образом типизировать простые действия как объект, функцию или даже Promise?

Возможно ли использовать async/await, как в примере справа?

4. Два вида действий

Задумайтесь, ведь действительно есть два вида действий:

  1. Reducer action: запускает редьюсер и изменяет состояние.
  2. Effect action: запускает асинхронное действие. Может вызвать reducer action, но асинхронная функция не способна напрямую изменить состояние.

Умение различать виды действий принесет больше пользы, чем использование «санков».

5. Никаких больше переменных хранящих тип действия

Почему принято разделять генераторы действий (action creators) и редьюсеры? Может ли один существовать без другого? Как изменить один не изменяя другой?

Генераторы действий и редьюсеры две стороны одной медали.

const ACTION_ONE = 'ACTIONE_ONE' — это лишний побочный эффект разделения генераторов действий и редьюсеров. Обращайтесь с ними как с единым целом и отпадет потребность в крупных файлах с экспортом типов.

6. Редьюсеры — это генераторы действий

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

В итоге, следуя этому сценарию, редьюсер может стать генератором действий.

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

  1. Если редьюсер получил название «increment», тогда тип будет «increment». Даже лучше, обозначим как «count/increment».
  2. Каждое действие передает данные через «payload».

Теперь при помощи count.increment мы можем создать генератор действий напрямую из редьюсера.

Хорошие новости: мы можем улучшить Redux

Эти проблемные части мотивировали на создание Rematch.

Rematch служит оберткой вокруг Redux, предоставляя разработчикам упрощенное API.

Вот полный пример кода с Rematch:

Я использовал Rematch в production последние несколько месяцев. И что я думаю:

Я никогда не тратил так мало времени на управление состоянием.

Redux не исчезнет и не обязан. Освойте эту библиотеку с меньшей кривой обучения, меньшим количеством бойлерплейта и меньшими умственными затратами.

Опробуйте Rematch и выясните, нравится он вам или нет.

Поставьте звезду, чтобы позволить узнать о нас другим.

Памятка · Документация Redux на русском языке

  • Документация Redux на русском языке
  • Содержание
  • Памятка

  • Введение

    • Мотивация

    • Базовые концепции

    • Три принципа

    • Предшественники

    • Образовательные ресурсы

    • Экосистема

    • Примеры

  • Основы

    • Экшены

    • Редюсеры

    • Сторона

    • Поток данных

    • Использование с React

    • Пример: список задач

  • Продвинутое использование

    • Асинхронные экшены

    • Асинхронные потоки

    • Мидлвар

    • Использование с React Router

    • Пример: Reddit API

    • Следующие шаги

  • Рецепты

    • Мигрирование на Redux

    • Использование оператора расширения

    • Упрощение шаблона

    • Серверный рендеринг

    • Написание тестов

    • Оперирование полученными данными

    • Реализация истории отмен

    • Изолирование саб-прило

.

Введение · Документация Redux на русском языке

  • Документация Redux на русском языке
  • Содержание
  • Памятка

  • Введение

    • Мотивация

    • Базовые концепции

    • Три принципа

    • Предшественники

    • Образовательные ресурсы

    • Экосистема

    • Примеры

  • Основы

    • Экшены

    • Редюсеры

    • Сторона

    • Поток данных

    • Использование с React

    • Пример: список задач

  • Продвинутое использование

    • Асинхронные экшены

    • Асинхронные потоки

    • Мидлвар

    • Использование с React Router

    • Пример: Reddit API

    • Следующие шаги

  • Рецепты

    • Мигрирование на Redux

    • Использование оператора расширения

    • Упрощение шаблона

    • Серверный рендеринг

    • Написание тестов

    • Оперирование полученными данными

    • Реализация истории отмен

    • Изолирование саб-приложений

.

Основы · Документация Redux

  • Документация Redux на русском языке
  • Содержание
  • Памятка

  • Введение

    • Мотивация

    • Базовые концепции

    • Три принципа

    • Предшественники

    • Образовательные ресурсы

    • Экосистема

    • Примеры

  • Основы

    • Экшены

    • Редюсеры

    • Сторона

    • Поток данных

    • Использование с React

    • Пример: список задач

  • Продвинутое использование

    • Асинхронные экшены

    • Асинхронные потоки

    • Мидлвар

    • Использование с React Router

    • Пример: Reddit API

    • Следующие шаги

  • Рецепты

    • Мигрирование на Redux

    • Использование оператора расширения

    • Упрощение шаблона

    • Серверный рендеринг

    • Написание тестов

    • Оперирование полученными данными

    • Реализация истории отмен

    • Изолирование саб-приложений

.

compose · документация Redux на русском языке

  • Документация Redux на русском языке
  • Содержание
  • Памятка

  • Введение

    • Мотивация

    • Базовые концепции

    • Три принципа

    • Предшественники

    • Образовательные ресурсы

    • Экосистема

    • Примеры

  • Основы

    • Экшены

    • Редюсеры

    • Сторона

    • Поток данных

    • Использование с React

    • Пример: список задач

  • Продвинутое использование

    • Асинхронные экшены

    • Асинхронные потоки

    • Мидлвар

    • Использование с React Router

    • Пример: Reddit API

    • Следующие шаги

  • Рецепты

    • Мигрирование на Redux

    • Использование оператора расширения

    • Упрощение шаблона

    • Серверный рендеринг

    • Написание тестов

    • Оперирование полученными данными

    • Реализация истории отмен

    • Изолирование саб-приложениC

.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *