How to setup Redux in React Next application?
First of all, install some packages which contain with Redux feature like:-
Redux, React Redux, Next Redux Wrapper, Redux Devtools Extension
after installing the above packages create a file in root project which name like store.js
it’s totally up-to-you for file naming but I am with store.js
& write codes like below
import { createStore, applyMiddleware } from 'redux'; import { composeWithDevTools } from 'redux-devtools-extension'; import { ADD_TO_CART, REMOVE_ITEM, SUB_QUANTITY, ADD_QUANTITY, ADD_SHIPPING, ADD_QUANTITY_WITH_NUMBER, RESET_CART } from './cart-actions' const initState = { products: [ { id: 1, title: "Pencil", price: 99, image: require("../../images/shop-image/1.jpg") }, { id: 2, title: "T-Shirt", price: 120, image: require("../../images/shop-image/2.jpg") }, { id: 3, title: "Casual Shoe", price: 160, image: require("../../images/shop-image/3.jpg") }, { id: 4, title: "Drop Side Watch", price: 130, image: require("../../images/shop-image/4.jpg") }, { id: 5, title: "Chair", price: 90, image: require("../../images/shop-image/5.jpg") }, { id: 6, title: "Card", price: 180, image: require("../../images/shop-image/6.jpg") } ], addedItems:[], total: 0, shipping: 0 } const cartReducer= (state = initState, action) => { if(action.type === ADD_TO_CART){ let addedItem = state.products.find(item => item.id === action.id) //check if the action id exists in the addedItems let existed_item= state.addedItems.find(item=> action.id === item.id) if(existed_item) { addedItem.quantity += 1 return { ...state, total: state.total + addedItem.price } } else { addedItem.quantity = 1; //calculating the total let newTotal = state.total + addedItem.price return { ...state, addedItems: [...state.addedItems, addedItem], total : newTotal } } } if(action.type === ADD_QUANTITY_WITH_NUMBER){ let addedItem = state.products.find(item => item.id === action.id) //check if the action id exists in the addedItems let existed_item= state.addedItems.find(item=> action.id === item.id) if(existed_item) { addedItem.quantity += action.qty return { ...state, total: state.total + addedItem.price * action.qty } } else { addedItem.quantity = action.qty; //calculating the total let newTotal = state.total + addedItem.price * action.qty return { ...state, addedItems: [...state.addedItems, addedItem], total : newTotal } } } if(action.type === REMOVE_ITEM){ let itemToRemove= state.addedItems.find(item=> action.id === item.id) let new_items = state.addedItems.filter(item=> action.id !== item.id) //calculating the total let newTotal = state.total - (itemToRemove.price * itemToRemove.quantity ); return { ...state, addedItems: new_items, total: newTotal } } if(action.type === ADD_QUANTITY){ let addedItem = state.products.find(item=> item.id === action.id) addedItem.quantity += 1 let newTotal = state.total + addedItem.price return { ...state, total: newTotal } } if(action.type === SUB_QUANTITY){ let addedItem = state.products.find(item=> item.id === action.id) //if the qt == 0 then it should be removed if(addedItem.quantity === 1){ let new_items = state.addedItems.filter(item=>item.id !== action.id) let newTotal = state.total - addedItem.price return { ...state, addedItems: new_items, total: newTotal } } else { addedItem.quantity -= 1 let newTotal = state.total - addedItem.price return { ...state, total: newTotal } } } if(action.type === ADD_SHIPPING){ return { ...state, shipping: state.shipping += 6 } } if(action.type === 'SUB_SHIPPING'){ return { ...state, shipping: state.shipping -= 6 } } if(action.type === RESET_CART){ return { ...state, addedItems: [], total: 0, shipping: 0 } } else { return state } } export const initStore = (initialState = initState) => { return createStore( cartReducer, initialState, composeWithDevTools(applyMiddleware()) ) }
Now create a file like cart-actions.js
//Types should be in const to avoid typos and duplication since it's a string and could be easily miss spelled export const ADD_TO_CART = 'ADD_TO_CART'; export const REMOVE_ITEM = 'REMOVE_ITEM'; export const SUB_QUANTITY = 'SUB_QUANTITY'; export const ADD_QUANTITY = 'ADD_QUANTITY'; export const ADD_SHIPPING = 'ADD_SHIPPING'; export const ADD_QUANTITY_WITH_NUMBER = 'ADD_QUANTITY_WITH_NUMBER'; export const ORDER_FORM = 'ORDER_FORM'; export const CHECKOUT_CHARGE = 'CHECKOUT_CHARGE'; export const RESET_CART = 'RESET_CART';
now create another file like cartActions.js
& codes like
import { ADD_TO_CART, REMOVE_ITEM, SUB_QUANTITY, ADD_QUANTITY, ADD_QUANTITY_WITH_NUMBER, RESET_CART } from './cart-actions' //add cart action export const addToCart = (id) => { return { type: ADD_TO_CART, id } } //remove item action export const removeItem = (id) => { return { type: REMOVE_ITEM, id } } //subtract qt action export const subtractQuantity = (id) => { return { type: SUB_QUANTITY, id } } //add qt action export const addQuantity = (id) => { return { type: ADD_QUANTITY, id } } //add qt action with quantity number export const addQuantityWithNumber = (id, qty) => { return { type: ADD_QUANTITY_WITH_NUMBER, id, qty } } // Reset cart after form submit export const resetCart = () => { return { type: RESET_CART } }
now open the _app.js
from pages folder & update codes like below
.... import { Provider } from 'react-redux'; import withRedux from 'next-redux-wrapper'; import { initStore } from '../cartReducer'; export default withRedux(initStore)( class MyApp extends App { static async getInitialProps ({ Component, ctx }) { return { pageProps: Component.getInitialProps ? await Component.getInitialProps(ctx) : {} } } render () { const { Component, pageProps, store } = this.props return ( <Provider store={store}> <Component {...pageProps} /> </Provider> ); } } )
That’s it, now the redux is working, open up the redux dev tools see the states like below
If you want to see full example codes then go to below links & download