Redux is a Flux-based state management library that uses pure function reducers to produce a predictable state object tree on the client . That state object exists as a single store that is read-only and can only be updated by using the one way data flow that you setup using the following elements (in data flow order):
Action Creators -> Actions -> Dispatch -> Reducers -> State
Action creators are functions that create actions and make it easier to use actions around our app.
Actions are objects that specify, as properties, a type and a payload.
Dispatch essentially creates a copy of the actions passes it to the reducer to process.
A Reducer is a pure function that takes the previous,state and an action and returns the next state. Based on the action.type, it will process its parameters accordingly.
Store is the state data object. It also acts as an api for the state via the following:
1. Lets you retrieve the state with getState(),
2. allows state to be updated via dispatch(action)
Redux is great for separating application and ui state from the presentation/UI. It is not tied to any specific UI library, though it did rise to popularity as a seeming cohort of React; there are API implementations for Vue and Angular too.
For bindings with React, you use React-Redux; which gives us connect() as a HOC binding for dispatch. We use this in container components as the default export, passing it the container component along with customary mapStateToProps() function which does basically what it says it does, map the redux state to props for consumption by child components.
We also get, from React-Redux, the Provider, which grants us access to the ‘context’ of the Store and thus passes access to that context to its descendants.
Along with the ability to follow the programming paradigm of single responsibility for data and presentation, Redux empowers UI engineers to have greater control over mutation of that state and the need for asynchronous events.
This is because of the principles the Redux enforces, like the use of pure functions, the one way data flow and the restriction of the flow as reducer(previousState, action) -> newState.
To extend Redux, for example to handle asynchronicity, we can include middleware like Redux Thunk and Redux Saga using the applyMiddleware() API within our createStore() function, which we use to configure our store.
This function also takes our reducers and an optional preloaded state. We package out multiple reducers using combineReducers().
You can create your file structure however you like, but often we create a folder for reducers, actions, middleware and the store. Actions and reducers are usually in a single index.js file within their folder and the store could have a single store file that references an environemnt variable to tell if we are in production or development. This,is useful because we might want to add logging with redux-logger and a connection for browser Devtools in development but not in production.
Redux is a useful tool for modern front end engineering that has to deal with complex UX demands with highly interactive and programmatic UIs handling I/O from/to many data destinations.