项目实践--创建项目
在store的modules中创建相关的子仓库暴露到仓库index文件中
导入creatSlice和axios
创建仓库 和数据的异步修改方法
// 编写store
// 导入createSlice和axios
import { createSlice } from "@reduxjs/toolkit";
import axios from "axios";
// 创建slice
const foodsStore = createSlice({name: "foods",initialState: {foodsList: [],},//修改foods的数据 需要配合异步请求函数reducers: {setFoodsList(state, action) {state.foodsList = action.payload;},},
});
编写异步请求函数
// 导出actions和reducer
const { setFoodsList } = foodsStore.actions;
const reducer = foodsStore.reducer;// 异步获取
const fetchFoodsList = () => {return async (dispatch) => {const res = await axios.get("http://localhost:3004/takeaway");const data = res.data;dispatch(setFoodsList(data));};
};
这存在一个后端接口返回值count 不准确的情况 使用双重foreach 将count变成1初始化
// 异步获取
const fetchFoodsList = () => {return async (dispatch) => {const res = await axios.get("http://localhost:3004/takeaway");const data = res.data;//将每一个子项里的foods里的每一项的的count都修改为1data.forEach((item) => {item.foods.forEach((food) => {food.count = 1;});});console.log(data);dispatch(setFoodsList(data));};
};
导出
// 导出fetchFoodsList
export { fetchFoodsList };
export default reducer;
store的index注册使用
// 导入 configureStore 和 foodsReducer
// 使用 configureStore 创建 store
import { configureStore } from '@reduxjs/toolkit';
import foodsReducer from './modules/takeaway';const store= configureStore({reducer: {foods: foodsReducer,},
});
export default store;
在App.js中调用仓库方法映射数据
// 导入useDispatch和useEffect和fetchFoodsList
import { useDispatch } from "react-redux";
import { useEffect } from "react";
import { fetchFoodsList } from "./store/modules/takeaway";
在App函数中调用
// 触发异步请求// 使用useDispatch获取dispatchconst dispatch = useDispatch();// 使用useEffect触发异步请求useEffect(() => {dispatch(fetchFoodsList());},[dispatch]);
使用仓库数据进行渲染
渲染数据 使用useSelector进行渲染
const {foodsList}=useSelector((state)=>state.foods);
MENU菜单的渲染和点击出发css事件
1、仓库中新建一个控制点击事件的activeIndex变量
const foodsStore = createSlice({name: "foods",initialState: {foodsList: [],activeIndex:0},//修改foods的数据 需要配合异步请求函数reducers: {setFoodsList(state, action) {state.foodsList = action.payload;},setActiveIndex(state,action){state.activeIndex=action.payload;}},
});
导出相关函数方法
import classNames from 'classnames'
import './index.scss'
import { useDispatch, useSelector } from 'react-redux';
import { setActiveIndex } from '../../store/modules/takeaway';const Menu = () => {const { activeIndex,foodsList } = useSelector(state => state.foods);const menus = foodsList.map(item => ({ tag: item.tag, name: item.name }))const dispatch=useDispatch();return (<nav className="list-menu">{/* 添加active类名会变成激活状态 */}{menus.map((item, index) => {return (<divonClick={()=>dispatch(setActiveIndex(index))}key={item.tag}className={classNames('list-menu-item',activeIndex===index && 'active')}>{item.name}</div>)})}</nav>)
}export default Menu
使用activeIndex和index匹配方法进行css样式控制
并且使用这个值控制菜单列的显示(记得导入activeIndex)
{/* 外卖商品列表 */}{foodsList.map((item,index) => {return (activeIndex===index && <FoodsCategorykey={item.tag}// 列表标题name={item.name}// 列表商品foods={item.foods}/>);})}
添加购物车
点击加号 一个list数组进行添加 如果是没有相关类目的 就进行push 如果有 就进行+1处理
首先添加一个cartList[] 设置相关方法
addCart(state, action) {// 判断是添加过过类目数据,如果添加过就进行add 没有就进行pushconst item = state.cartList.find((item) => item.id === action.payload.id);if (item) {item.count++;} else {state.cartList.push(action.payload);}},
导出相关字段与方法
在加法按钮中添加相关方法
<div className="goods-count"><spanclassName="plus"onClick={() =>dispatch(addCart({id,picture,name,unit,description,food_tag_list,month_saled,like_ratio_desc,price,tag,count,}))}>+</span></div>