React shopping cart example using react-redux and @reduxjs/toolkit approach

Tip: After the article is written, the table of contents can be automatically generated. How to generate it can refer to the help document on the right

Article directory

  • Preface
  • 1. What is react-redux
    • introduce
    • Why use react-redux
  • 2. Usage steps
    • 1. Import the library
    • 2.Create store
    • 3. Create slices
    • 4. Use the Provider component in react-redux to wrap the entire root component and pass the store
    • 5. Introduce the method exposed in the cart module in components/list.js
    • cart.js file (shopping cart)
  • Summarize

Foreword

Tip: Here you can add the general content to be recorded in this article:

For example: With the continuous development of artificial intelligence, the technology of machine learning is becoming more and more important. Many people have started to learn machine learning. This article introduces the basic content of machine learning.

Reminder: The following is the text of this article, the following case is for reference

1. What is react-redux

Official website: https://react-redux.js.org

Introduction

  • React Redux is the official React UI binding layer for Redux. It lets your React components read data from the Redux store and dispatch actions to the store to update state
  • React Redux is maintained by the Redux team and keeps up with the latest APIs from Redux and React
  • Intended to be used with React’s component model. You define how to extract the values needed by the component from Redux, and the component is automatically updated as needed
  • Provides an API to enable your components to interact with the Redux store so you don’t have to write that logic yourself
  • Automates complex performance optimizations so that your own components are only reloaded when the data it needs actually changes
    rendering

Why use react-redux

  • Can help us subscribe to the store, check updated data and trigger re-rendering of components

2. Usage steps

1. Import the library

Download react-redux and @reduxjs/toolkit:

npm i react-redux @reduxjs/toolkit
npm i react-router-dom@6
npm i axios

2. Create store

The code is as follows (example):

// store/index.js
import {<!-- --> configureStore } from '@reduxjs/toolkit';
import cart from './modules/Cart'
// 1. Create store
const store = configureStore({<!-- -->

reducer:cart.reducer

})
export default store

3. Create slices

// store/modules/cart.js //Take the shopping cart as an example
import {<!-- --> createSlice } from '@reduxjs/toolkit';
const cart = createSlice({<!-- -->
name: 'cart', // namespace
initialState: {<!-- --> // Initialization data
num: 0,
cart:[]
},
reducers: {<!-- -->
  //Add product to shopping cart
    addCart(state, {<!-- --> payload }) {<!-- -->
      // Determine whether the current product exists in the shopping cart
      const idx = state.cart.findIndex(item => item.id === payload.id);
      if(idx !== -1) {<!-- --> // Prove that the current product exists in the shopping cart
        state.cart[idx].num + = 1; //Quantity + 1
      } else {<!-- -->
        state.cart.push(payload)
      }
    },
    // Modify the status of items in the shopping cart
    changeState(state, {<!-- --> payload: id }) {<!-- --> // Rename payload to id
      // Find subscript based on id
      const idx = state.cart.findIndex(item => item.id === id);
      // change status
      state.cart[idx].checked = !state.cart[idx].checked;
    },
    // select all
    chooseAll(state, {<!-- --> payload:checked }) {<!-- -->
      // Loop through the products in the shopping cart to keep the status of each product consistent with the status of the select all button
      state.cart.forEach(item => {<!-- -->
        item.checked = checked;
      })
    },
    // Modify the quantity of the product
     changeNum(state, {<!-- --> payload }) {<!-- -->
      // Find subscript based on id
      const idx = state.cart.findIndex(item => item.id === payload.id);

      switch(payload.type) {<!-- -->
        case 'addNum' : // Click the plus button
          state.cart[idx].num + + ;
          break;
        case 'descNum' : // Clicked on the plus button
          state.cart[idx].num > 1 & amp; & amp; state.cart[idx].num--;
         break;
        default:
          state.cart[idx].num = payload.num * 1;
      }
    }
}
})
// reduxjs toolkit merges reducers and actions together
export const {<!-- --> addCart, changeState, chooseAll, changeNum } = counterSlice.actions;
// reducers everywhere
export default cart;

4. Use the Provider component in react-redux to wrap the entire root component and pass the store

import React from 'react';
import ReactDOM from 'react-dom/client';
//v6 routing
import {<!-- --> RouterProvider } from 'react-router-dom'
import router from './router'
//react-redux
import {<!-- --> Provider } from 'react-redux'
import store from './store'

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React. StrictMode>
<Provider store={<!-- --> store }>
<RouterProvider router={<!-- --> router } />
</Provider>
</React.StrictMode>
)

5. Introduce the methods exposed in the cart module into components/list.js

import React, {<!-- --> useEffect, useState } from 'react'
import {<!-- --> useNavigate } from 'react-router-dom';
import axios from 'axios';
import {<!-- --> useDispatch } from 'react-redux';
import {<!-- --> addCart } from '../../store/modules/cart';
import "./index.scss"
export default function List() {<!-- -->
  const navigate = useNavigate(); //Route jump method
  const [list, setlist] = useState([]);
 
  const dispatch = useDispatch(); // dispatch action

  //Encapsulate the method of obtaining product list data
  const getList = async () => {<!-- -->
    const {<!-- --> data } = await axios.get('/data.json');
    setlist(data);
  }
  
  //Add product to shopping cart
  const addGoods = goods => {<!-- -->
    dispatch(addCart({<!-- --> ...goods, num: 1, checked: false }))
  }

  // Encapsulate the method of rendering the product list
  const renderList = () => (
    list.map(item => (
      <li key={<!-- --> item.id }>
        <div className="img-box">
          <img src={<!-- -->'/imgs/' + item.img } alt="" />
        </div>
        <div className="goods-info">
          <div className="goods-title">{<!-- --> item.title }</div>
          <div className="goods-info-footer">
            <div className="goods-price">{<!-- --> item.price }</div>
            <div className="add-cart" onClick={<!-- --> () => addGoods(item) }>Add to shopping cart</div>
          </div>
        </div>
      </li>
    ))
  )

  useEffect(() => {<!-- -->
    getList();
  }, [])

  return (
    <div className="goods-list">
      <div className="goods-list-content">
        <div className="go-cart" onClick={<!-- --> () => navigate('/cart') }>Go to shopping cart</div>
        <ul className="list">{<!-- --> renderList() }</ul>
      </div>
    </div>
  )
}

cart.js file (shopping cart)

import React, {<!-- --> useMemo } from 'react'
import {<!-- --> useNavigate } from 'react-router-dom'
// useSelector: get data, useDispatch: dispatch action
import {<!-- --> useSelector, useDispatch } from 'react-redux';
// Modify product status, select all, modify quantity
import {<!-- --> changeState, chooseAll, changeNum } from '../../store/modules/cart';
export default function Cart() {<!-- -->
  const navigate = useNavigate();
  // Get the data in redux
  const cart = useSelector(store => store. cart);
  const dispatch = useDispatch();
  //The state of the select all button
  const checkedAll = useMemo(() => cart.every(item => item.checked));
  // Manually modify the quantity of items in the shopping cart
  const updateNum = (id, ev) => {<!-- -->
    if(!isNaN(ev.target.value)) {<!-- -->
      dispatch(changeNum({<!-- --> type: 'changeNum', id, num: ev.target.value }))
    } else {<!-- -->
      dispatch(changeNum({<!-- --> type: 'changeNum', id, num: 1 }))
    }
  }
  // Triggered when focus is lost
  const blur = (id, ev) => {<!-- -->
    ev.target.value == 0 & amp; & amp; dispatch(changeNum({<!-- --> type: 'changeNum', id, num: 1 }))
  }
  //Encapsulate the method of rendering the shopping cart list
  const renderCart = () => (
    cart.map(item => (
      <li key={<!-- --> item.id }>
        <div className="checkbox">
          <input type="checkbox" checked={<!-- --> item.checked } onChange={<!-- --> () => dispatch(changeState(item.id)) } />
        </div>
        <div className="goods-info">
          <div className="img-box">
            <img src={<!-- -->'/imgs/' + item.img } alt="" />
          </div>
          <div className="goods-introduce">{<!-- --> item.title }</div>
        </div>
        <div className="goods-price">¥{<!-- --> (item.price).toFixed(2) }</div>
        <div className="goods-controler">
          <div className="desc" onClick={<!-- -->() => dispatch(changeNum({<!-- --> type: 'descNum', id: item.id }))}>- </div>
          <div className="input-wrapper">
            <input type="text" value={<!-- --> item.num } onChange={<!-- --> ev => updateNum(item.id, ev) } onBlur={<!-- -->ev => blur(item.id, ev)} />
          </div>
          <div className="add" onClick={<!-- -->() => dispatch(changeNum({<!-- --> type: 'addNum', id: item.id }))}> + </div>
        </div>
        <div className="goods-total">¥{<!-- --> (item.price * item.num).toFixed(2) }</div>
        <div className="del-btn">Delete</div>
      </li>
    ))
  )
  return (
    <div className="cart-wrapper">
      <div className="cart-content-wrapper">
        <div className="cart-title">
          <h3>Shopping cart</h3>
          <div className="go-list" onClick={<!-- --> () => navigate('/list') }>Return to product list</div>
        </div>
        {<!-- -->
          cart.length?
          <>
            <div className="cart-list">
              <li>
                <div className="checkbox">
                  <input type="checkbox" />
                </div>
                <div className="goods-info-title">Goods information</div>
                <div className="goods-price-title">Unit price</div>
                <div className="goods-num-title">Quantity of goods</div>
                <div className="goods-total-title">Amount</div>
                <div>Operation</div>
              </li>
              {<!-- --> renderCart() }
            </div>
            <div className="footer-wrapper">
              <div className="left-box">
                <label>
                  Select all: <input type="checkbox" checked={<!-- --> checkedAll } onChange={<!-- --> ev => dispatch(chooseAll(ev.target.checked)) } />
                </label>
                <div className="del-choose-btn">Delete</div>
              </div>
              <div className="right-box">
                <div className="choose-goods-total">
                  <span>Selected products</span>
                  <span>0</span> items
                </div>
                <div className="total-price">Total: <span>0</span></div>
                <div className="settlement-btn disabled">Settlement</div>
              </div>
            </div>
          </>
          :
          <div className="empty-cart">
            Dear, you have not purchased any products <router-link to="/list">Hurry up and go shopping!</router-link>
          </div>
        }
      </div>
    </div>
  )
}

Summary

Tip: Here is a summary of the article:
For example: the above is what we will talk about today. This article only briefly introduces the use of pandas, and pandas provides a large number of functions and methods that allow us to process data quickly and easily.