Redux is a Single Source of Truth:
this means the state of the whole application is stored in an object tree with a single store. This is different than its predecessor and perhaps, source of inspiration, Flux, which has multiple stores.
State is Read Only:
The only way to change state is to emit an action, which can be instantiated by action creators. An action is an object describing what happened. This makes it so that Redux is in charge of its data, not the UI not API callbacks. The data is in state is also immutable, and so you replace the existing state, based on the prescribed action, with a new state.
Changes are made with Pure Functions:
To specify how the state tree is updated by actions, you write pure reducers. This is largely a functional programming concept, borrowed or inspired by the creator of Redux, Dan Abramov’s work with Elm Lang.
A pure reducer is just a pure function that happens to resolve a reducer function. Pure functions have no side effect and will always yield the same result given the same input. They are highly testable, make good use of memoization and are parallelizable and so make good candidates for piping.
Since Redux is a low-weight library that follows a very good programming credo of doing one thing and doing it well, often times, like the React library it is often paired with, other libraries are needed to achieve certain functionality in ‘the wild’. This is great because you can use Redux as the central data store for the front of your app and take it into other UI platforms, like Native, VR, TV, etc.
This is also very fortunate, because you can really focus on what you want to use Redux for by choosing which libraries you want to include. These other libraries are referred to as middleware and one category of such middleware is for async functionality. Since Redux uses pure functions, async and other side effect driven goals can’t really be done idiomatically.
Having the entire state available anywhere in the app has its advantages too. When you’ve gotten to a point that sharing the state around the app is to difficult to do with just a single parent component, then Redux can be very helpful to avoid tunneling and the increasing feeling of precarious integrity that comes with it. Of course, there are techniques and APIs like RenderProps and Context API to help with things, but Redux lifts the state to a separate place. RenderProps and Context API can still be helpful patterns when going between Containers and Component or smart and dumb components.
It’s always important to keep the following steps in mind when creating a global app state object with Redux.
For me, it is is bit of a minimal check list.
Create a logical and intuitive folder structure for project assets and features
Create Components & Containers that pass renderProps or Context to the app
Create indexes for types, reducers and actions
Configure the store with createStore()
Memoize the state for interaction data