В этой статье мы собираемся изучить реализацию Redux (популярный вариант Flux) с Derivable.
Redux против Derivable
Простите, что заголовок статьи вызывает кликабельность. Реализация Redux, о которой мы собираемся здесь поговорить, не будет полной, и в этом нет никакого смысла.
Сам Redux очень полезен для использования вместе с Derivable в его текущей форме: это будет темой следующей статьи. Итак, нет Redux vs. Derivable.
Конечно, встает вопрос о добавленной стоимости использования Derivable с Redux. Мы обсудим это позже.
Архитектура Redux
Архитектура Redux настолько проста в ретроспективе. Итак, мы собираемся просто показать реализацию:
import {atom, derivation} from 'derivable' function createStore(reduce, initialState = {}) { let store = atom(initialState) return { store: derivation(() => store.get()) dispatch: (action) => { let nextState = reduce(store.get(), action) store.set(nextState) } } }
Это все, что требуется (10 LOC), чтобы реализовать шаблон архитектуры, подобный Redux, с помощью Derivable. Конечно, это чрезмерное упрощение: например, промежуточное ПО не поддерживается.
Затем мы могли бы использовать createApplication для определения приложения, передав ему начальное состояние и редуктор, который позаботится об обработке действий и превращении их в обновления состояния:
let {store, dispatch} = createApplication( function reduce(state, action) { if (action.type === 'ADD_TODO') { return { ...state, todoList: state.todoList.concat(action.text) } } else { throw new Error('unknown action type: ' + action.type) } }, {todoList: []} ) function addTodo(text) { dispatch({type: 'ADD_TODO', text}) }
Обратите внимание, что атом, который хранит состояние, предоставляется не напрямую, а через наследование и функцию dispatch (). Это запрещает прямые мутации состояний.
Привязки к React
Интересно то, что нам не нужны какие-то специальные привязки к React, мы можем повторно использовать React Derivable, который мы обсуждали в предыдущих статьях.
import React from 'react' import {reactive} from 'react-derivable' let TodoList = reactive(props => { let todoList = store.get().todoList return ( <div> <ul>{todoList.map(todo => <li>{todo}</li>)}</ul> <button onClick={() => addTodo('new todo!')}> Add todo </button> </div> ) })
Это одно из преимуществ единого уровня управления реактивным состоянием: мы можем повторно использовать фрагменты кода между различными стратегиями управления состоянием.
Но Derivable дает еще одно преимущество при использовании его вместе с Redux: эффективный уровень запросов для состояния приложения. Об этом мы поговорим в следующей статье.