Redux
Redux is an open source js library for managing your application's state. Redux is commonly used with js libraries like reactjs and frontend frameworks such as angular. A redux store works on the principle of a javascript reducer where the centralised application state is updated with the help of an action dispatcher. An action dispatcher dispatches an action object which describes what is to be done with the application state. An action object is a simple js object with keys "type" and "payload". "type" describes the action to be performed and "payload" is the actual data used to update or mutate the application state. Here's an example of an action object :
{type:'ADD_ITEM',payload:'Android'}
'ADD_ITEM' describes the action event and 'Android' is the data to be mutated in the state.
To make it clear, go through the following code snippet:
const initialState={
items:[]
}
function rootReducer=(state=initialState,action){
switch(action.type){
case 'ADD_ITEM':
return {...state,items:[...state.items,action.payload]}
case 'REMOVE_ITEM':
const filteredItems=state.items.filter(item=>item!==action.payload)
return {...state,items:filteredItems}
default:
return {...state}
}
}
Create a store with redux
Upto this point, I hope the concepts of state, action and dispatch objects might be clear. The next question is how do I create a store and update it with the help of action objects. For this, install the redux library using npm or you can go with a cdn if node is not installed in your system.
npm install redux
redux has made it possible to create a centralised store easily with a single line of code. All you have to do is, pass the reducer as an argument to the createStore() function of redux. This acts as a channel to dispatch your action objects and listen to state updates. Go through the modified snippet below :
import {createStore} from 'redux';
const initialState={
items:[]
}
function rootReducer=(state=initialState,action){
switch(action.type){
case 'ADD_ITEM':
return {...state,items:[...state.items,action.payload]}
case 'REMOVE_ITEM':
const filteredItems=state.items.filter(item=>item!==action.payload)
return {...state,items:filteredItems}
default:
return {...state}
}
}
const store=createStore(rootReducer);
console.log(store.getState());
store.dispatch({type:'ADD_ITEM',payload:'Android'})
store.dispatch({type:'ADD_ITEM',payload:'ios'})
console.log(store.getState());
store.dispatch({type:'REMOVE_ITEM',payload:'Android'})
console.log(store.getState());
Try to guess the outputs of the console.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
{items:['Android','ios']}
{items:['Android']}
This was a just a jist of the redux architecture. As mentioned already, redux is the perfect option for a centralised persistent state that goes well with reactjs.
Now to connect your store with your react application, install react-redux library. Assuming you are using npm package manager with a module bundler like webpack or browersify :
npm install react-redux
Now wrap your top level component, usually App.js , with a component, with your store passed as a prop. You can do this in index.js file too.
index.js
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import {Provider} from 'react-redux';
import {store} from './configureStore.js';
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<Provider store={store}><App /></Provider>
</StrictMode>,
rootElement
);
The above code snippet assumes you create a store in configureStore.js file in the same way as we did earlier. Now you can use the centralised state in your components without the need to prop drill through the components. Make use of useDispatch() and useSelector() hooks to dispatch an action object and get state values. Following code snippet gives an idea on how to use these two handy hooks :
import React,{useState} from 'react';
import {useDispatch,useSelector} from 'react-redux';
export default (props)=>{
const [newItem,setNewItem]=useState('');
const dispatch=useDispatch();
const state=useSelector();
function newItemHandler(){
dispatch({type:'ADD_ITEM',payload:newItem})
}
return (
<div>
{!state.items.length?<h1>List is empty</h1>:
<ul>
{state.items.map(item=><li>{item}</li>)}
</ul>
}
<input
type="text"
placeholder="add new item"
value={newItem}
onChange={e=>setNewItem(e.target.value}
/>
<button onClick={newItemHandler}>Add New Item</button>
</div>
);
}
Top comments (0)