Redux is a state management tool for javascript apps. It allows you to share the state between components.
Why use Redux?
- When we have big complicated data for complex applications.
- Any component can pull any piece of data from the redux store. So data needs to be shared between multiple components
Story of a Store
To understand redux, let’s imagine a hypothetical story. We can then get into the details of it.
Let’s say there is a STORE ๐ฌ which currently has chocolates ๐ซ ( initialState of store ). There is a person called ‘ACTION CREATOR’ that creates cookies ๐ช ( action ) and sends ( dispatches an action ) it to another person called ‘REDUCER’.
The ๐ผ job of REDUCER is to check the type of food ( payload ) and if its ‘COOKIES’ then create a new container ( object ), put cookies ‘Hide n seek’ inside of it and send it to the store.
The ๐ฎ gatekeeper called ‘SUBSCRIBER’ whose job is to keep listening and watching ๐ the updates in the store materials, will then tell you that store received/updated with the new item cookies.
Earlier STORE only had chocolates but after cookies were dispatched and REDUCER gave store cookies as well, the STORE now has both chocolate ๐ซ and cookies ๐ช .
Since you get the basic idea of the process from the story, Let’s understand each of these terms in detail.
Install Redux
npm i redux
// Assuming that you have the create-react-app or the build set up with webpack and babel.
Initializing the state
Let’s initialize a state and set its initial values:
// Initialize initialState.
const initialState = {
chocolate: 'Dairy Milk'
};
Create Reducer
A reducer:
- type: Object ( Pure Function )
- Takes
prevState
andaction
as parameters - Checks the type of action and creates a newState with the updated values, accordingly
- Returns a newState.
- Updates store with newState
Initializing the// Create Reducer.
/**
*
* @param prevState ( the first time its value is equal to initialState,
* and then after every dispatch of action, automatically gets the value of the previous state,
* just before action creates a new state with new values )
* @param action
*
* @return {Object} newState ( after creating a new state based on the action type. Also called nextState )
*/
const reducer = ( prevState, action ) => {
console.warn( 'prevState', prevState );
// Set newState to prevState.
let newState = prevState;
if ( 'SNACKS' === action.type ) {
newState = { ...prevState, cookies: action.payload }
}
return newState;
};
Create a Store
A store:
- type: Object
- has methods like:
- dispatch
- subscribe
- getState, etc.
- createStore() takes
reducer
function andinitialState
as parameters - createStore() creates a store
/**
* Create a store.
*
* @param {Object} reducer Reducer function.
* @param {Object} reducer Initial State.
*
* @type {Object} store.
*/
const store = createStore( reducer, initialState );
Create action using Action Creators:
Actions are:
- type: object ( events )
- have type and payload ( e.g.
{ type: 'COOKIES' , payload: 'Hide n Seek' }
Action Creators are:
- type: Object
- Functions that wrap action ( objects ) and return those actions ( objects )
/**
* Action creator.
*
* @return {Object} action.
*/
const getLastName = () => {
// Action.
const actionOne = {
type: 'COOKIES',
payload: 'Hide and Seek'
};
return actionOne;
};
// Get the value of action.
const myAction = getLastName();
Subscribe to the Store
Subscribers are:
- type: Object ( functions )
- Functions that listen and respond to the updates to the state values in store.
- Calls the function inside of it when state value of store gets updated with the new one.
// Listen to any change in store, and calls the function inside of it, when state updates with a new one.
store.subscribe( () => {
console.warn( 'newState', store.getState() ); // After state updates with a new one.
} );
Dispatch an action
When the action is dispatched using store.dispatch()
the reducer checks the type of the action and creates a new state and updates the store with the new state. Because Subscriber is listening to update in the state of. the store, it calls the function inside of it.
store.dispatch( myAction );
Full Code
import { createStore } from "redux";
// Initialize initialState.
const initialState = {
chocolate: 'Dairy Milk'
};
// Create Reducer.
/**
*
* @param prevState ( the first time its value is equal to initialState,
* and then after every dispatch of action, automatically gets the value of the previous state,
* just before action creates a new state with new values )
* @param action
*
* @return {Object} newState ( after creating a new state based on the action type. Also called nextState )
*/
const reducer = ( prevState, action ) => {
console.warn( 'prevState', prevState );
// Set newState to prevState.
let newState = prevState;
if ( 'SNACKS' === action.type ) {
newState = { ...prevState, cookies: action.payload }
}
return newState;
};
/**
* Create a store.
*
* @param {Object} reducer Reducer function.
* @param {Object} reducer Initial State.
*
* @type {Object} store.
*/
const store = createStore( reducer, initialState );
/**
* Action creator.
*
* @return {Object} action.
*/
const getLastName = () => {
// Action.
const actionOne = {
type: 'COOKIES',
payload: 'Hide and Seek'
};
return actionOne;
};
// Get the value of action.
const myAction = getLastName();
// Listen to any change in store, and calls the function inside of it, when state updates with a new one.
store.subscribe( () => {
console.warn( 'newState', store.getState() ); // After state updates with a new one.
} );
store.dispatch( myAction );