Redux — the holy cow for modern React Application. But is it enought `Reactish`? To say the truth — no.  [https://blog.codecentric.de/en/2017/12/developing-modern-offline-apps-reactjs-redux-electron-part-3-reactjs-redux-basics/](https://blog.codecentric.de/en/2017/12/developing-modern-offline-apps-reactjs-redux-electron-part-3-reactjs-redux-basics/) ### “Reactish” TODO-list Lets try to build iconic TODO-list application using React only. > code is listen in a reverse order // first - create a underlying data structure const TODOs = \[todo1, todo2, todo3\]; // second pass into Application const Application = <TodoList todos={TODOs} /> // third define todo list const TodoList = ({todos}) => ( <ol> {todos.map( todo => <Todo key={todo.id} {...todo} /> </ol> ); // last define Todo const Todo = (props) => <div>......</div> The key feature here is — **All the data for a child was passed by it’s parent**. ### “Redux” TODO-list Lets try to rework this into redux variant > This is simplified version of the [original Redux’s Todo list](https://github.com/reactjs/redux/tree/master/examples/todos) // first - create a underlying data structure const store = createStore({ todos: \[todo1, todo2, todo3\] }); // second pass into Application const Application = <Provider store={store}> <ConnectedTodoList/> </Provider> // third connect todo list const ConnectedTodoList = connect( state => ({todos: state.todos}) // <- here we inject the data )(TodoList) // forth define todo list const TodoList = ({todos}) => ( <ol> {todos.map( todo => <Todo key={todo.id} {...todo} /> </ol> ); // last define Todo const Todo = (props) => <div>......</div> The key feature here is — at any point you could connect to the global store. Get data, and dispatch events. This decouples a whole application, but, actually, makes parts of an Application less composable. > Even more — **Component composition** (another holy cow of React) just **will not work**, as long redux ignores it’s position in time and space. ### A bit more “redux-ish” TODO-list So. I could mention the one moment here, which could be improved. TodoList is too `reactish`. And Todo is absolutely not `reduxish`. Lets fix it .... // third connect todo list const ConnectedTodoList = connect( state => ({todos: idsFrom(state\[todos\])})// only ID, not all data )(TodoList) ... // forth define todo list const TodoList = ({todos}) => ( <ol> {todos.map( todo => <ConnectedTodo key={todo.id} id={todo.id} /> </ol> ); // use props to get the desired data const ConnectedTodoList = connect( (state, props) => ({...state.todos\[props.id\]}) // get the TODO )(Todo) // last define Todo const Todo = (props) => <div>......</div> This is faaaaar more better. TodoList is invariant to any change in Todo’s data, and TODO element is connected directly to the store. This is also quite cool, cos it creates borders for an event propagation. > Redux’s connect **is the** **start** for any update, as long it connected directly to the store, and triggered directly. > Redux’s connect **is the** **end** for any update, as long it is a PureComponent, and will pass only changes, inducted by the Redux Store, not React update. It’s like an octopus, handling and drowning your app. > Think about the origins of things. Beginning, and ending.  ### The final battle Lets pick another example. Almost todo list, but with nesting. Here is the link to the sources. [**reactjs/redux** _redux - Predictable state container for JavaScript apps_github.com](https://github.com/reactjs/redux/blob/master/examples/tree-view/src/containers/Node.js "https://github.com/reactjs/redux/blob/master/examples/tree-view/src/containers/Node.js")[](https://github.com/reactjs/redux/blob/master/examples/tree-view/src/containers/Node.js) The key feature here — you got a Node, and that node got a list inside. And to update/edit that list you have to specify `nodeId`, not only `listId`. And redux failed to `purely` solve this problem. They could not “normally” provide dispatch with nodeId prefilled, and they shall not provide nodeId for List, to let List select data from the store. What they could do? They use **React** handlers to do **Redux** work. handleAddChildClick = e => { // get nodeId and dispatch function from a parent const { addChild, createNode, id } = this.props; const childId = createNode().nodeId; // dispatch event with both variables known addChild(id, childId) } > This breaks component approach. This is fail. ### Restate to the rescue > Redux-restate, Redux-tree, re-store, Redux-Lenses, Transformation… redux is missing all these things, and **Restate** is all these things. Restate is a brand new library, which enables your application to become both more Reactish, and more Reduxish. And solves the problems of the last example. How? Lets create an example: .... // third connect todo list const ConnectedTodoList = connect( state => ({todos: idsFrom(state\[todos\])})// only ID, not all data )(TodoList) ... // forth define todo list Mapper const TodoList = ({todos}) => ( <ol> {todos.map( todo => <ReconnectedTodo key={todo.id} id={todo.id} /> </ol> ); // create a new redux connection point (**HERE IS THE MAGIC**) // "focus" into the derived state const ReconnectedTodo = **reduxFocus**( // keep only selected TODO in the store **(state, pros) => { todo: state.todos\[id\] },** // \`restore\` TODO id is on dispatch (dispatch, event, props) => dispatch({...event, id: props.id}) )(ConnectedTodo); // use props to get the desired data const ConnectedTodoList = connect( (state) => ({...state.todo}) // a single todo HERE, the right one )(Todo) // last define Todo const Todo = (props) => <div>......</div> _PS: reduxFocus is a part of Redux Restate._ This example uses `react-redux-focus` — this simpler version of `react-redux-restate`, which is a “react” version of `redux-restate`. > This solves main redux (global state) issue: reusability. Get the control, form sub-states, sub-stores. Map and reduce. Compose. May be you already have a `connected` component, tightly bound to some state structure just by fetching some keys from the state? You know — that component is not reusable. Throw it away const ConnectedXComponent = connect(mapStateToProps)(MyXComponent); .... // just wrap it with redux state "adapter". Why not? const ReusableXConnectedComponent = reduxFocus( (state,props) => createXState(state, props) )(ConnectedXComponent) #### What it does? `reduxFocus` creates the new store from the current one, **focusing** the “bigger” state for the children. ConnectedTodo will have to accept only a single TODO, and it will be isolated from any other data, it does not need. _(ie will be focused)_ In the same time, as long reduxFocus scopes the data, there is no need to pass down “id”, to use it in dispatch, as long you could **augment** all **events passing back** to the original store with `todoId` you know. Thus also means, that you could place TODO-list in a Trello-like tree, just define _lense_ to get a single TODO-list from a “big” store, and place “nodeid” to all the events, a nested component will dispatch in a future. > This will enable Component model, so beloved by everyone. ### More complex example? React-redux-focus is a simple HOC, designed to work with a single store. The original `React-redux-restate` is designed to work with more the one store. But why?? const mapStateToProps = state => { something: memoizedWithReselect(someComplexOperation(state)) } connect(mapStateToProps)(Component) How often Component’s **render** method be called? Everytime some `real` update will pass memoization, and trigger update. So — not often. How often `someComplexOperation` will be called? Everytime state got updated. Even if you will also memoize it — you will call memoized function… a lot. From ReactRedux `render` method. > If you have 100500 connection to the store — all of them will call mapStateToProps on every store update. Unless you will specify areStatesEqual, but you will not. **Restate** IS that **areStatesEqual** — a “lensed” small part of a global store for the children, and isolate them from the rest. // default store will be accessible as \`default\`. const NestedStore = restate({}, ({ default:state }) => ({ state.only, state.data, state.i, state.need }))(RenderChildren); But next you might need the original data once again. But also might need the computed data from the `current`, sintetic store. const Reprovider = reprovider('superStore'); // copy store to the superStore const NestedNestedStore = restate( { base: 'superStore' }, // get \`superStore\` as \`base\` ({ default: state, base }) => ({ ...state, base.dataFromBase}) (dispatchers, event, props) => { dispatch dispatches.default or dispatcher.base? })... This is not the best example, but sometimes it is possible to have to stores in a single application, for example “Application” and “Page”, and work restate will enable you to combine the data from both of them, and route dispatch back to the correct store. > Even more — two stores is common way to work with MobX ### Is it still redux? The good question, as long few things may break the core concepts. 1. Is it ok to create derivered store from a store? _In database world it called views or mat-views(as long they are memoized). You do the same with mapStateToProps. It is ok from a theory point of view._ 2\. Is it ok to `route` dispatches back? Bubbling yet again? _First — there is no other way. Second — as long routeDispatch is a pure function (same as mapStateToProps or reducers) — it is_ `_predictable_`_. As long store behavior is predictable — it is ok._ 3\. Is it ok to make containers sensitive to the place in a tree? _This part was missing. With restate application can use redux in a better way — more often, more easier, more correct._ 4\. Is it a real `redux` store? _No. This is just a view with redux-like public interface, reusable by redux’s connect down the tree. It’s fake._ The current way to solve some sort of tasks is just not correct. Recall the Tree-example — not React, not Redux, just hacks around. ### You don’t need Redux? It could sounds a bit odd, but **Restate is ok without Redux.** You can merge one or more states together, or you can **form a new state from props,** mapping dispatch to React’s component methods. **return** ( /\* <ReduxFocus focus={**bigState => smallState**}> \*/ <ReduxFocus focus={**this**.getState}> <ReduxDelay timeout={500}> counter: <Counter /> /\* will connect to "redux" \*/ </ReduxDelay> </ReduxFocus> ); So restate — is a powerfull state management library. Fully React and Redux ideologically compatible. ### Time to try? Restate was releases literally yesterday, but it is ready. The original repo contains more examples, documentation, and a bit more theory about. [**theKashey/restate** _restate - Make redux composable again!_github.com](https://github.com/theKashey/restate "https://github.com/theKashey/restate")[](https://github.com/theKashey/restate) Let redux be composable again! Let the component architecture bloom! I’ve got a 3(already 5) package for you. Pick the one you need: // to low-level redux manupulations import reduxRestate from 'redux-restate'; // to work with multiple stores import reactReduxRestate from 'react-redux-restate'; // to focus a lens on a single store import reactReduxFocus from 'react-redux-focus'; // to freeze the time import reactReduxSemaphore from 'react-redux-semaphore'; // to optimize state changes import reactReduxDelay from 'react-redux-delay'; // to optimize update propagation import reactReduxUnbranch from 'react-redux-unbranch'; PS: The actual code is just 10–50 LoC per componet. Somethings might become more clear, if you will just read the code. #### Follow up article [**The State of the State of the State** _In other words — Fractal State. To be more concrete — Redux Fractal State. It is possible to create Fractal using…_blog.cloudboost.io](https://blog.cloudboost.io/the-state-of-the-state-of-the-state-f93c8bdc6b1b "https://blog.cloudboost.io/the-state-of-the-state-of-the-state-f93c8bdc6b1b")[](https://blog.cloudboost.io/the-state-of-the-state-of-the-state-f93c8bdc6b1b)