REDUX EXPLAINED
WHAT IS REDUX AND WHY IS REDUX USED
‘Redux is a predictable state container for JavaScript apps’ WRITTEN ON OFFICIAL DOCS
SO THAT BASICALLY MEANS REDUX IS A CONTAINER WHERE A STATE IS KEPT WHICH CAN BE ACCESSED BY ANY COMPONENT AND USED BY THEM.
FOR EXAMPLE IF WE HAVE HEADER FOOTER AND CONTENT AS 3 DIFFERENT COMPONENTS AND ONE OF THE DATA IN THE STATE OF CONTENT IS NEEDED TO B SHOWN ON HEADER THEN HOW TO PASS THE VALUE??
THIS CAN B A BIT MESSY IF WE HAVE MANY COMPONENTS ,ROUTES AND BASICALLY A BIGGER APP
FOR ALL THOSE SITUATIONS WE NEED A UNIVERSAL STATE TO HOLD THOSE DATAS WHICH IS USED BY MANY COMPONENTS
ANOTHER EXAMPLE CAN BE :
AMAN HAS 3 TOY CARS , HIS SIBLING NISHI HAS 2 DOLLS AND THEIR MOTHER HAS 2 TOYS . SO AMAN WOULD BORROW THOSE 2 TOY CARS FROM HIS MOM AND PLAY AND NISHI CAN ALSO BORROW THOSE SAME CARS AND PLAY ALONG WITH PLAYING WITH THEIR OWN RESPECTIVE TOYS WHICH NONE OF THE OTHER TOUCHES!!!(TYPICAL SIBLING STUFF 😂)
VERY SIMPLE!
HOPE THIS EXAMPLES MADEU UNDERSTAND A LITTLE BIT OF USAGE OF REDUX
U WILL UNDERSTAND MORE ONCE U READ THE EXAMPLE BELOW
— BASIC STEPS FOR REDUX —
1. MAKE A ACTIONTYPE
FIRST OF ALL ACTIONTYPES R THE STRINGS WHICH HOLD A CERTAIN VALUE
EXAMPLE:
export const INCREMENT = “INCREMENT”;export const DECREMENT = “DECREMENT”;export const ADDTODO = “ADDTODO”;export const EDITTODO = “EDITTODO”;export const DELETETODO = “DELETETODO”;
2. MAKE A ACTION FOR IT
ACTIONS R ARROW FUNCTIONS WHICH RETURN A TYPE (MANDATORY) . THIS R THE SAME TYPES WE DEFINED EARLIER AS ACTIONTYPES.
NOW THIS ACTIONS CAN RETURN ANY OTHER DATA AS WELL (i.e WE CAN PASS ARGUMENTS TO ACTIONS AS WELL)
EXAMPLE:
export const increment = () => {
return {
type: types.INCREMENT,};};export const decrement = () => {return {type: types.DECREMENT //NO ARGUMENTS R PASSED SO RETURNING ONLY TYPE};};export const completed = id => {return {type: types.COMPLETED,id};};export const edittodo = (text, id) => { //ARGUMENTS R PASSED AND R RETURNING THEM ALONG WITH TYPEreturn {type: types.EDITTODO,text: text,id: id};};export const deletetodo = item => {return {type: types.DELETETODO,item: item};};
```
3. MAKE A REDUCER FOR THIS ACTION (WHICH WILL BE CALLED WHEN THAT ACTION IS DISPATCHED)
THIS R THE ARROW FUNCTIONS WHERE ACTUAL LOGIC OF ANY ACTION TAKES PLACE . WHENEVER A ACTION IS DISPATCHED THAT PARTICULAR REDUCER STARTS WORKING AS WELL
EXAMPLE:
//A BASIC TODO REDUCER
export const todos = [];const tdo = (state = todos, action) => {switch (action.type) {case types.ADDTODO: //HERE THIS FUNCTION IS MATCHED WITH THE DISPATCHED ACTION’S TYPE THEN IT IS CALLED IF MATCHEDreturn updateList(state, { //THE LIST IS UPDATED WITH NEW VALUESid: action.id,text: action.text,completed: false});case types.EDITTODO:return state.map(todo =>todo.id === action.id ? { …todo, text: action.text } : todo);}}export default tdo;
//A BASIC COUNTER REDUCER
const initialState = {counter: 0};export const increment = (state, action) => { //VALUE OF THE COUNTER IS INCREMENTEDreturn updatedObj(state, { counter: action.counter });};export const decrement = (state, action) => {return updatedObj(state, { counter: state.counter — 1 });};const reducer = (state = initialState, action) => {switch (action.type) {case types.INCREMENT:return increment(state, action); //HERE IT IS MATCHED WITH THE DISPATCHED ACTION’S TYPE THEN IT IS CALLED IF MATCHEDcase types.DECREMENT:return increment(state, action);default:return state;}};export default reducer;
```
4. CREATE A STORE AND WRAP THE PARENT COMPONENT IN PROVIDER (WHICH HAS THAT STORE)
TILL NOW WE WERE DOING BASIC PROGRAMMING OF ACTIONS AND REDUCERS
NOW WE R CONNECTING THE REDUCERS AND THEIR STATE TO STORE WHICH IS PARENT FOR ALL OTHER COMPONENTS
JUST DIVE INTO THE CODE AND U WILL UNDERSTAND EVERY PART OF IT
import { createStore, applyMiddleware, compose } from “redux”;import { Provider } from “react-redux”;import rootReducer from “./store/reducers”; //THIS IS THE REDUCERimport thunk from “redux-thunk”;import BasicLayout from “./Layout”; //THIS IS THE BASE COMPONENTconst composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; //THIS IS NEEDED FOR REDUX DEVTOOLS CHROMEconst store = createStore(rootReducer,composeEnhancers(applyMiddleware(thunk)) //MIDDLEWARE IS APPLIED WITH THUNK BECOZ IT WILL HELP IN ASYNCHRONUS ACTIONS);ReactDOM.render(<Provider store={store}> //WRAPPING OF BASE USING PROVIDER<BasicLayout /></Provider>,document.getElementById(“root”));
5. MAP STATE TO PROPS AND USE THEM IN THE COMPONENTS
DURING PREVIOUS STEPS A STORE IS CREATED WHICH HAS THE DATA OF STATE DEFINED IN REDUCERS.
NOW TO CONNECT THE COMPONENTS WITH THE STORE/STATE WE NEED CONNECT FUNCTION AND THIS IS WHERE MAP STATE TO PROPS COME IN.
AS THE NAME SUGGESTS THIS FUNCTION JUST MAPS THE STATE TO PROPS AND THEN IT CAN BE USED BAY THAT PARTICULAR COMPONENT AS PROPS
EXAMPLE:
//THIS FUNCTION MAPS THE STATE’S COUNTER FROM COUNTER REDUCER TO BE PASSED AS ‘counter’ PROP TO THE APP COMPONENT
const mapStateToProps = state => {return {counter: state.counter.counter};};export default connect(mapStateToProps)(App); //HERE IS HOW IT IS CONNECTED TO HEADER (U NEED TO IMPORT CONNECT THOUGH)<h4>{this.props.counter}</h4> // HERE IS HOW IT IS ACCESSED AND USED
MAP DISPATCH TO PROPS
Dispatching functions mapped to props which will dispatch certain actions on calling those prop functions
EXAMPLE:
constructor(props) {super(props);this.state = {name: “”};}onSubmit = e => {e.preventDefault();const name = this.state.name;this.props.addTodo(name);//calling the function mapped to propsthis.setState({ name: “” });};onChange = e => {this.setState({ name: e.target.value });};
<div className=”container”>// inside rendering jsx component<form onSubmit={this.onSubmit}><Inputvalue={this.state.name}onChange={this.onChange}placeholder=”enter todo items”/></form></div>const mapDispatchToProps = dispatch => {return {
//mapping action disapatch to a function to props
addTodo: text => dispatch(addtodo(text))
};};
//connecting to App component
export default connect(mapStateToProps, mapDispatchToProps)(App);