Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 2ea5a9a

Browse files
使用useReduce优化state
1 parent 926f0fc commit 2ea5a9a

File tree

5 files changed

+134
-88
lines changed

5 files changed

+134
-88
lines changed

‎README.md‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,7 @@ const B = () => {
6262
所以 `setState()`方法可以不设置到依赖中
6363
如果依赖项设置了一个空数组,则意味 `Effect` 只会在组件初始化时触发一次
6464

65-
- React.memo
66-
memo 只会根据 props 判断是否需要重新渲染,和 state 和 context 无关,state 或 context 发生变化时,组件依然会正常的进行重新渲染
65+
- `React.memo`
66+
`memo` 只会根据 `props` 判断是否需要重新渲染,和 `state``context` `无关,state``context` 发生变化时,组件依然会正常的进行重新渲染
67+
68+
- `useReducer` 可以优化复杂的 `state`

‎src/App.js‎

Lines changed: 76 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,98 @@
1+
import { useCallback, useState, useReducer } from 'react'
12
import { ConfigProvider } from 'antd'
3+
24
import Meals from './components/meals'
35
import Search from './components/search'
46
import Cart from './components/cart'
57
import cartContext from './store/cart'
6-
import { useCallback, useState } from 'react'
7-
8-
// 模拟一组食物数据
9-
const MEALS_DATA = [
10-
{
11-
id: '1',
12-
title: '汉堡包',
13-
desc: '百分百纯牛肉配搭爽脆酸瓜洋葱粒与美味番茄酱经典滋味让你无法抵挡!',
14-
price: 12,
15-
img: '/img/hamburger1.png'
16-
},
17-
{
18-
id: '2',
19-
title: '双层吉士汉堡',
20-
desc: '百分百纯牛肉与双层香软芝,加上松软面包及美味酱料,诱惑无人能挡!',
21-
price: 20,
22-
img: '/img/hamburger2.png'
23-
},
24-
{
25-
id: '3',
26-
title: '巨无霸',
27-
desc: '两块百分百纯牛肉,搭配生菜、洋葱等新鲜食材,口感丰富,极致美味!',
28-
price: 24,
29-
img: '/img/hamburger3.png'
30-
}, {
31-
id: '4',
32-
title: '麦辣鸡腿汉堡',
33-
desc: '金黄脆辣的外皮,鲜嫩幼滑的鸡腿肉,多重滋味,一次打动您挑剔的味蕾!',
34-
price: 21,
35-
img: '/img/hamburger1.png'
36-
}, {
37-
id: '5',
38-
title: '板烧鸡腿堡',
39-
desc: '原块去骨鸡排嫩滑多汁,与翠绿新鲜的生菜和香浓烧鸡酱搭配,口感丰富!',
40-
price: 22,
41-
img: '/img/hamburger2.png'
42-
}, {
43-
id: '6',
44-
title: '麦香鸡',
45-
desc: '清脆爽口的生菜,金黄酥脆的鸡肉。营养配搭,好滋味的健康选择!',
46-
price: 14,
47-
img: '/img/hamburger3.png'
48-
}, {
49-
id: '7',
50-
title: '吉士汉堡包',
51-
desc: '百分百纯牛肉与香软芝士融为一体配合美味番茄醬丰富口感一咬即刻涌现!',
52-
price: 12,
53-
img: '/img/hamburger1.png'
8+
import { MEALS_DATA } from './mock'
9+
10+
const reduce = (state, action) => {
11+
let newMeal = { ...state }
12+
let { type, item } = action
13+
switch (type) {
14+
case 'ADD':
15+
newMeal.amount++
16+
newMeal.totalPrice += item?.price
17+
if (newMeal?.items?.indexOf(item) === -1) {
18+
newMeal?.items?.push(item)
19+
item.count = 1
20+
21+
} else {
22+
item.count++
23+
}
24+
break
25+
26+
case "REMOVE":
27+
newMeal.totalPrice -= item?.price
28+
newMeal.amount--
29+
item.count--
30+
if (item.count === 0) {
31+
newMeal?.items?.splice(newMeal.items.indexOf(item), 1)
32+
}
33+
break
34+
35+
case "CLEAR":
36+
newMeal?.items?.forEach(meal => delete meal.count)
37+
newMeal.items = []
38+
newMeal.amount = 0
39+
newMeal.totalPrice = 0
40+
break
41+
42+
default:
43+
newMeal = state
44+
break
5445
}
55-
]
46+
return newMeal
47+
}
48+
5649

5750
function App () {
5851
const [mealsData, setMealsData] = useState(MEALS_DATA)
59-
const [cartData, setCartData] = useState({
52+
const [cartData, cartDispatch] = useReducer(reduce,{
6053
items: [],
6154
totalPrice: 0,
6255
amount: 0
6356
})
6457

6558
// 添加商品
66-
const addItem = (item) => {
67-
let newMeal = { ...cartData }
68-
newMeal.amount++
69-
newMeal.totalPrice += item?.price
70-
if (newMeal.items.indexOf(item) === -1) {
71-
newMeal.items.push(item)
72-
item.count = 1
59+
// const addItem = (item) => {
60+
// let newMeal = { ...cartData }
61+
// newMeal.amount++
62+
// newMeal.totalPrice += item?.price
63+
// if (newMeal.items.indexOf(item) === -1) {
64+
// newMeal.items.push(item)
65+
// item.count = 1
7366

74-
} else {
75-
item.count++
76-
}
77-
setCartData(newMeal)
78-
}
67+
// } else {
68+
// item.count++
69+
// }
70+
// setCartData(newMeal)
71+
// }
7972

8073
// 删除商品
81-
const removeItem = (item) => {
82-
let newMeal = { ...cartData }
83-
newMeal.totalPrice -= item?.price
84-
newMeal.amount--
85-
item.count--
86-
if (item.count === 0) {
87-
newMeal.items.splice(newMeal.items.indexOf(item), 1)
88-
}
89-
setCartData(newMeal)
90-
}
74+
// const removeItem = (item) => {
75+
// let newMeal = { ...cartData }
76+
// newMeal.totalPrice -= item?.price
77+
// newMeal.amount--
78+
// item.count--
79+
// if (item.count === 0) {
80+
// newMeal.items.splice(newMeal.items.indexOf(item), 1)
81+
// }
82+
// setCartData(newMeal)
83+
// }
9184

9285
// 清空购物车
93-
const clearCart = () => {
94-
let cart = {
95-
items: [],
96-
amount: 0,
97-
totalPrice: 0
98-
}
99-
let meals = [...mealsData]
100-
meals.forEach(meal => delete meal.count)
101-
setCartData(cart)
102-
}
86+
// const clearCart = () => {
87+
// let cart = {
88+
// items: [],
89+
// amount: 0,
90+
// totalPrice: 0
91+
// }
92+
// let meals = [...mealsData]
93+
// meals.forEach(meal => delete meal.count)
94+
// setCartData(cart)
95+
// }
10396

10497
// 搜索
10598
const filterData = useCallback((keyWord) => {
@@ -116,7 +109,7 @@ function App () {
116109
}, [setMealsData])
117110

118111
return (
119-
<cartContext.Provider value={{ ...cartData, addItem, removeItem, clearCart }}>
112+
<cartContext.Provider value={{ ...cartData, cartDispatch }}>
120113
<ConfigProvider theme={{ token: { colorPrimary: '#ffcd00' } }}>
121114
<div style={{ width: '750rem', height: '100vh', overflow: 'hidden', position: 'relative' }}>
122115
<Search filterFn={filterData}></Search>

‎src/components/cart/detail/index.js‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ function Detail ({ meals }) {
1717
}
1818

1919
const confirm = () => {
20-
ctx.clearCart()
20+
ctx.cartDispatch({ type: 'CLEAR' })
21+
2122
}
2223

2324
const cancel = () => {

‎src/components/meals/counter/index.js‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@ import CartCtx from '../../../store/cart'
55

66
function Counter ({ meal }) {
77
const ctx = useContext(CartCtx)
8+
// 新增
89
const add = () => {
9-
ctx.addItem(meal)
10+
ctx.cartDispatch({type: 'ADD',item: meal})
1011
}
12+
// 删除
1113
const remove = () => {
12-
ctx.removeItem(meal)
14+
ctx.cartDispatch({type: 'REMOVE',item: meal})
1315
}
16+
1417
return (
1518
<div className={counterCss.counterBox}>
1619
{

‎src/mock/index.js‎

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
export const MEALS_DATA = [
2+
{
3+
id: '1',
4+
title: '汉堡包',
5+
desc: '百分百纯牛肉配搭爽脆酸瓜洋葱粒与美味番茄酱经典滋味让你无法抵挡!',
6+
price: 12,
7+
img: '/img/hamburger1.png'
8+
},
9+
{
10+
id: '2',
11+
title: '双层吉士汉堡',
12+
desc: '百分百纯牛肉与双层香软芝,加上松软面包及美味酱料,诱惑无人能挡!',
13+
price: 20,
14+
img: '/img/hamburger2.png'
15+
},
16+
{
17+
id: '3',
18+
title: '巨无霸',
19+
desc: '两块百分百纯牛肉,搭配生菜、洋葱等新鲜食材,口感丰富,极致美味!',
20+
price: 24,
21+
img: '/img/hamburger3.png'
22+
}, {
23+
id: '4',
24+
title: '麦辣鸡腿汉堡',
25+
desc: '金黄脆辣的外皮,鲜嫩幼滑的鸡腿肉,多重滋味,一次打动您挑剔的味蕾!',
26+
price: 21,
27+
img: '/img/hamburger1.png'
28+
}, {
29+
id: '5',
30+
title: '板烧鸡腿堡',
31+
desc: '原块去骨鸡排嫩滑多汁,与翠绿新鲜的生菜和香浓烧鸡酱搭配,口感丰富!',
32+
price: 22,
33+
img: '/img/hamburger2.png'
34+
}, {
35+
id: '6',
36+
title: '麦香鸡',
37+
desc: '清脆爽口的生菜,金黄酥脆的鸡肉。营养配搭,好滋味的健康选择!',
38+
price: 14,
39+
img: '/img/hamburger3.png'
40+
}, {
41+
id: '7',
42+
title: '吉士汉堡包',
43+
desc: '百分百纯牛肉与香软芝士融为一体配合美味番茄醬丰富口感一咬即刻涌现!',
44+
price: 12,
45+
img: '/img/hamburger1.png'
46+
}
47+
]

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /