项目实践--创建项目
在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都修改为1
data.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获取dispatch
const 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 (
<div
onClick={()=>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 && <FoodsCategory
key={item.tag}
// 列表标题
name={item.name}
// 列表商品
foods={item.foods}
/>
);
})}
添加购物车
点击加号 一个list数组进行添加 如果是没有相关类目的 就进行push 如果有 就进行+1处理
首先添加一个cartList[] 设置相关方法
addCart(state, action) {
// 判断是添加过过类目数据,如果添加过就进行add 没有就进行push
const item = state.cartList.find((item) => item.id === action.payload.id);
if (item) {
item.count++;
} else {
state.cartList.push(action.payload);
}
},
导出相关字段与方法
在加法按钮中添加相关方法
<div className="goods-count">
<span
className="plus"
onClick={() =>
dispatch(
addCart({
id,
picture,
name,
unit,
description,
food_tag_list,
month_saled,
like_ratio_desc,
price,
tag,
count,
})
)
}
>
+
</span>
</div>