Easy Way to understand Redux
- why do we use Redux in React
- install redux
- create store
- reducer function
- store (dispatch, subscribe, getState)
- create store second parameter (initial State)
- combine reducers
- create store third parameter (middleware)
Why do we use Redux in React
- redux is a little difficult to understand for the first time, but it is very useful.
- should use when the data of your application is bigger and the data must change over time.
- redux keeps your data in one place (store) and give back when an action pass to it.
- all the data combine in a place and we can easily use data what we want.
There are only three things to understand for redux
Store
- create a store to store all data in our app
Reducer function
example reducer function
function reducer(data = 0, action){
switch(action.type){
case "Add":
data = data + 1;
;break;
case "Sub":
data = data - 1;
; break;
default : return data ;
} return data;
}
- is a function connect to store that return a new state for store
- and store change with new data.
action creator
- to change data from store an action must give
As above example,
If an action of type = ‘Add’, reducer function will return new data (adding 1) and store data change;
An action give action type to store , data in store change according to action type passing through to reducer function.
redux install (npm)
npm install redux
Create Store
Store is an object that holds the complete state of your app.
https://redux.js.org/api/createstore
- import createStore from redux
- create a store with createStore()
- pass a function (reducer) to createStore
Example -> src/ index.js
import { createStore } from 'redux';function reducer(){}const store = createStore(reducer)
Above codes are not the complete code.
Reducer function
Reducer is a function that pass to store. Instead of the name reducer , you can give anything you like. Reducer function needs two arguments State and Action. Reducer function must return the new state according to an action.
State of store changes because of an action.
Example -> src/ index.js
import {createStore} from 'redux';function reducer(state = 0, action){
if(action.type === 'Add'){
state = state + 1;
console.log(state);
}
return state;
}const store = createStore(reducer);store.dispatch({type: 'Add'});
The object in store can only change with dispatch function. As the above example dispatch function pass action (an object) to reducer function.
The reducer function will return state (1) because dispatch function pass the action type to ‘Add’.
Store (dispatch, subscribe, getState)
- store.dispatch() — the only way to change the state data. dispatch must pass action to reducer function.
- store.subscribe() — call the function when the store change
- store.getState() — return the state with current data
import {createStore} from 'redux';function reducer(state = 0, action){
if(action.type === 'Add'){
state = state + 1;
}
return state;
}const store = createStore(reducer);store.subscribe(() => {
console.log(store.getState());
})store.dispatch({type: 'Add'});
Create store second parameter (initial State)
Now we gonna pass two parameter to store.
- reducer (first parameter)
- initial state (second parameter)
function reducer(state, action){
if(action.type === 'Add'){
state = state + 1;
}
return state;
}const store = createStore(reducer, 1);
Pass the initial state to 1 and state equal 1. If dispatch pass the action with the type ‘Add’ it will return 2 Or not return 1.
Combine reducers
In real app, initial state of store can complex and you will use more than one reducer to return different state value.
combineReducer combined all the child reducer function to an object and return that object and pass it to createStore.
Example
const reducers = combineReducers({
newItem: newItemReducer,
total: totalReducer
})const store = createStore(reducers);
src/index.js
import {combineReducers, createStore} from 'redux';function newItemReducer(state = {}, action){
if(action.type === 'changeItem'){
state.newItem = action.newItem
}
return state;
}function totalReducer(state = 0, action){
if(action.type === 'changeTotal'){
state = state + action.num
}
return state;
}const reducers = combineReducers({
newItem: newItemReducer,
total: totalReducer
})const store = createStore(reducers);store.subscribe(() => {
console.log(store.getState());
})store.dispatch({type: 'changeItem', newItem: 'Apple'});
store.dispatch({type: 'changeTotal', num: 6});
- newItemReducer and totalReducer pass to combineReducers
- are gathered to an object
- assign to reducers
- pass to createStore
Create store third parameter (middleware)
Redux middleware supports to create async action and it acts between dispatching an action and the moment it reaches the reducer.
People use Redux middleware for logging, crash reporting, talking to an asynchronous API, routing, and more.
import {applyMiddleware, createStore} from 'redux';const store = createStore(reducer, applyMiddleware(logger));
applyMiddleware needs a function as an argument. As the above example logger function.
- middleware argument (logger) receives store dispatch , getState
- return a function will be given the next middleware's dispatch method
- and return action
logger function
function logger(store){
console.log(store); //output {getState: ƒ, dispatch: ƒ}
return next => {
return action => {
console.log(action); // output {type: “ADD”}
next(action)
}
}
}
to test
src/index.js
import {applyMiddleware, createStore} from 'redux';function reducer(state = 0, action){
if(action.type === 'ADD'){
state = state + 1;
console.log(state);
}
return state;
}function logger(store){
console.log(store);
return next => {
return action => {
console.log(action);
next(action)
}
}
}const store = createStore(reducer, applyMiddleware(logger));store.dispatch({type: 'ADD'});