Разве вас не беспокоил огромный объем работы, который вам придется проделать с проектом, если вы используете Redux в качестве инструмента управления состоянием?

Хотите использовать Relessjs немедленно? Перейдите на npmjs.com/package/relessjs

У меня есть! Особенно, когда проект растет. Затем я хочу оставить вещи СУХИМИ и поместить мои Типы действий в одно место, потому что мне нужно везде ссылаться на них. Да, я знаю, вы все еще можете вставить туда струны { type: “FILTER" }, но тогда я должен сопоставить их с моими редюсерами, чтобы они были уже мокрыми (не СУХИМИ).

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

Реализация поиска в Redux

Допустим, у меня есть приложение ToDo, и я хочу, чтобы todo фильтровались на основе текста. Простая функция поиска. Чтобы реализовать это, мне пришлось бы сделать следующее:

  1. добавить тип действияvar actions = { filter: “FILTER” } в todo-actions.js (здесь я поместил все свои константы, чтобы убедиться, что он остается СУХИМ)
  2. импортировать todo-actions.js в todo-reducers.js
  3. создать новое дело для actions.filter в reducer
  4. импортировать todo-actions.js в search-component.js
  5. реализовать dispatch({ type: actions.filter, payload: event.target.value }), чтобы запустить цикл

Да, слишком… много… работы…Мы можем сделать лучше:

  • удалить шаг 1 (нет необходимости в типе действия);
  • удалить шаг 2 (без типов действий означает: без констант);
  • удалить шаг 4 (там же); и
  • вместо шага 5 (вызов dispatch()) мы просто вызовем редюсерreducers.search(payload) и
  • реализовать шаг 3 в редукторе

Реализация поиска в Reless

Я строил Relessjs. Пакет, обеспечивающий те же основные концепции архитектуры Flux, что и Redux, но с меньшими затратами.

Итак, теперь мы просто вызываем Reducer из View и получаем новое State, в котором View будет перерисовано.

Relessjs: однонаправленный поток данных без накладных расходов

Теперь моя новая функция поиска в приложении ToDo упрощена до двух шагов:

  1. Создайте редьюсер с именем search(payload)в список редьюсеров из Reless.
  2. Вызов reducers.search(input.value) из нового компонента поиска

Потрясающе правильно! Просто создайте и вызовите.

Простота: создайте редьюсер, вызовите редьюсер

Сила Релесса

Ниже приведены несколько примеров возможностей, которые может предложить Reless.

Установка значения, чтобы просто установить состояние, редюсер имеет следующий тип payload => state: функция, которая получает payload и возвращает новый частичный state. Частичное состояние, потому что оно объединяется с существующим состоянием. Это устраняет необходимость в Object.assign({}, value) или { ...state } на корневом уровне.

Увеличение счетчика, обновление состояния на основе другого состояния:

Как показано выше (установка значения), вы не получаете состояние в качестве второго параметра в первой функции. Для использования состояния Reless позволяет вернуть функцию из редуктора типа state => state. Таким образом, вы можете использовать state, переданный во второй функции.

var store = new Reless({
  state: { counter: 0 },
  reducers: {
    increment: payload => state => ({ counter: state.counter + 1 })
  }
})

Извлечение данных, некоторые асинхронные действия (и использование частичного состояния):

Ну, теперь вы знаете упражнение. Вы можете вернуть другую функцию типа reducers => state, где вы можете вызвать другую reducer таким же образом, как указано выше, и/или вернуть state, которая вступает в силу сразу после завершения функции.

var store = new Reless({
  state: { todos: [] },
  reducers: {
    getAllTodos: payload => state => reducers => {    
      fetch('some.url/api/todos')
        .then((todos) => reducers.setTodos(todos))
      return ({ loading: true })
    },
    // since Reless does a merge we can return
    // a partial state instead of a full state
    setTodos: todos => ({ todos })
})

Обратный отсчет таймера, постоянное выполнение чего-либо в зависимости от последнего состояния:

Для этого нам нужно сделать небольшую хитрость. Вместо того, чтобы вызывать редюсер с payload, мы вызываем его с другой функцией, которая возвращает полезную нагрузку state => payload. Таким образом мы получаем доступ к последней версии state.

(В приведенном ниже конкретном случае вы также можете просто вызвать decrement, но в других случаях вы можете вызвать reducer (setCounter) с полезной нагрузкой)

var store = new Reless({
  state: { counter: 20 },
  reducers: {
    decrement: () => state => ({ state.counter: state.counter-1 }),
    setCounter: payload => ({ counter: payload }),
    getAllTodos: payload => state => reducers => {       
      var countdownHandle = setInterval(() => {
        if (state.counter)
          reducers.setCounter(state => state.counter - 1)
        else 
          clearInterval(countdownHandle)
      }, 1000)
    }
})

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