Ashun's 技術駅 Ashun's 技術駅
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • HTML
  • CSS
  • Vue
  • 现代web布局
  • React
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 技术资源
  • 第一阶段

    • HTML
  • 第二阶段

    • JavaScript
  • 第三阶段

    • Vue
  • 第四阶段

    • 实战项目
  • 每周测试

    • 每周
  • 其他

    • Vue引入UI框架
    • Web前端面试
    • Vue3-resource
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 福利资源
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Ashun

前端界的小学生
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • HTML
  • CSS
  • Vue
  • 现代web布局
  • React
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 技术资源
  • 第一阶段

    • HTML
  • 第二阶段

    • JavaScript
  • 第三阶段

    • Vue
  • 第四阶段

    • 实战项目
  • 每周测试

    • 每周
  • 其他

    • Vue引入UI框架
    • Web前端面试
    • Vue3-resource
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 福利资源
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 核心概念

  • 高级指引

  • Hook

  • 案例演示

  • 商医通项目

    • react基础笔记
    • typescript笔记
    • antd基本使用
    • react项目笔记
    • 课件-react路由-V6
    • 课件-redux-toolkit
      • 1. 基本使用
      • 2. 添加商品
      • 3. 添加购物车
      • 4. 拆分模块
        • 1. 目录结构
      • 5. 视图操作添加商品购物车
      • 使用步骤
    • 课件-国际化
    • 课件-其他hooks
    • 课件-虚拟dom和diff算法
  • 《React》笔记
  • 商医通项目
ashun
2024-01-22
目录

课件-redux-toolkit

# redux toolkit

redux toolkit: 官方提供的redux工具包

作用:对数据状态进行集中式管理

react-redux:在react中更方便的使用redux

# 1. 基本使用

  1. 下载
yarn add @reduxjs/toolkit
npm install @reduxjs/toolkit
1
2
  1. src->index.js
/**
 * 
 * redux toolkit 集中式状态管理
 * 
 */
// 1. 引入模块
import {
    createSlice, // 通过该函数创建数据状态管理模块
    configureStore // 生成仓库
} from '@reduxjs/toolkit'

//2.  创建切片:createSlice 函数返回的是一个对象
const countSlice = createSlice({
    // 模块名字
    name:'counter',
    // 初始状态值
    initialState:{
        count:1
    },
    // 提供方法用于操作状态
    reducers:{
        // 会在countSlice对象的actions属性上增加一个方法 increment
        // state:
        // 如果是第一次执行,那么state值为你的 initialState
        // 如果非第一次执行,那么state值为上一次操作的结果
        // action 是通过dispatch 执行时传递过来的action
        increment(state,action){
            // 在这里可以直接改
            // 1. 不需要对状态进行复制
            // 2. 不需要return
            state.count += action.payload
        }
    }
})

//3. 创建仓库
const store = configureStore({
    reducer:{
        counter:countSlice.reducer
    }
})
console.log(countSlice,store)

// 唯一正确的获取状态数据的途径,getState()返回一个对象,对象的结构与 configureStore传入的参数对象结构相同
// 状态与仓库的关系: state = store.getState()
console.log(store.getState()) // {counter:{count:1}}
console.log(store.getState().counter) // 获得counter模块的状态

//4.  获取状态
const state = store.getState()

// 5. 更改状态
// 错误的方式:不允许直接修改
// state.counter.count = 100;

// 正确的方式:store.dispatch()

// 获取操作counter仓库的 actionCreater 函数 increment. increment(值) 执行的结果会返回一个action {type:'片名/reducer中操作函数名',payload:值}
const {increment} = countSlice.actions
console.log(increment(2)) // {type:'counter/increment',payload:2}
store.dispatch(increment(1))
console.log(store.getState())

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

# 2. 添加商品

import {
    createSlice,
    configureStore
} from '@reduxjs/toolkit'

const goodsSlice = createSlice({
    name:'goods',
    initialState:{
        goodsList:[]
    },
    reducers:{
        addGoods(state,{payload}){
            state.goodsList.unshift({
                id:Math.random().toString(30).slice(2),
                ...payload
            })
        }
    }
})

const store = configureStore({
    reducer: {
        goods:goodsSlice.reducer,
    }

})

const {addGoods} = goodsSlice.actions

// 可一个给state增加监听,当state发生变化的时候,执行回调函数
// 监听方法的返回值,是一个函数,执行可以取消监听
const unsubscribe = store.subscribe(()=>{
    console.log(store.getState())
})
store.dispatch(addGoods({
    name:'华为手机',
    price:1999,
    num:1
}))

unsubscribe()
store.dispatch(addGoods({
    name:'华为电脑',
    price:9990,
    num:1
}))
console.log(store.getState())

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

# 3. 添加购物车

import {
    createSlice,
    configureStore
} from '@reduxjs/toolkit'
const goodsSlice = createSlice({
    name:'goods',
    initialState:{
        goodsList:[]
    },
    reducers:{
        addGoods(state,{payload}){
            state.goodsList.unshift({
                id:Math.random().toString(30).slice(2),
                ...payload
            })
        }
    }
})

// 添加购物车模块
const carSlice = createSlice({
    name:'car',
    initialState:{
        totalPrice:0,
        carList:[]
    },
    reducers:{
        addCar(state, {payload}){
            const info = state.carList.find(v=>{
                return v.id === payload.id
            })
            if(info){
                info.buyNum += 1
            }else{
                state.carList.unshift({
                    ...payload,
                    buyNum:1
                })
            }
            state.totalPrice =  state.carList.reduce((pre,cur)=>(pre + cur.buyNum * cur.price),0)
        }
    }
})
const store = configureStore({
    reducer: {
        goods:goodsSlice.reducer,
        car:carSlice.reducer
    }
})
const {addGoods} = goodsSlice.actions
const {addCar} = carSlice.actions

// 可一个给state增加监听,当state发生变化的时候,执行回调函数
// 监听方法的返回值,是一个函数,执行可以取消监听
const unsubscribe = store.subscribe(()=>{
    console.log(store.getState())
})
store.dispatch(addGoods({
    name:'华为手机',
    price:1999
}))

// unsubscribe()
store.dispatch(addGoods({
    name:'华为电脑',
    price:9990
}))

store.dispatch(addCar(store.getState().goods.goodsList[0]))
store.dispatch(addCar(store.getState().goods.goodsList[0]))
store.dispatch(addCar(store.getState().goods.goodsList[0]))
store.dispatch(addCar(store.getState().goods.goodsList[1]))
store.dispatch(addCar(store.getState().goods.goodsList[1]))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

# 4. 拆分模块

# 1. 目录结构

src
 |--store                     仓库
 |    |- slice                模块
 |    |    |- car.js          购物车模块
 |    |    |- goods.js        商品模块
 |    |- index.js             store
 |- index.js                  测试代码
1
2
3
4
5
6
7
  • src->store->index.js
import { configureStore } from "@reduxjs/toolkit"
import goods from './slice/goods'
import car from './slice/car'
const store = configureStore({
    reducer: {
        goods,
        car
    }
})
export default store
1
2
3
4
5
6
7
8
9
10
  • src->store->slice->car.js
import {
    createSlice
} from '@reduxjs/toolkit'

// 添加购物车模块
const carSlice = createSlice({
    name:'car',
    initialState:{
        totalPrice:0,
        carList:[]
    },
    reducers:{
        addCar(state, {payload}){
            const info = state.carList.find(v=>{
                return v.id === payload.id
            })
            if(info){
                info.buyNum += 1
            }else{
                state.carList.unshift({
                    ...payload,
                    buyNum:1
                })
            }
            state.totalPrice =  state.carList.reduce((pre,cur)=>(pre + cur.buyNum * cur.price),0)
        }
    }
})
export const {addCar} = carSlice.actions
export default carSlice.reduce
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  • src->store->slice->goods.js
import {
    createSlice
} from '@reduxjs/toolkit'
const goodsSlice = createSlice({
    name:'goods',
    initialState:{
        goodsList:[]
    },
    reducers:{
        addGoods(state,{payload}){
            state.goodsList.unshift({
                id:Math.random().toString(30).slice(2),
                ...payload
            })
        }
    }
})
export const {addGoods} = goodsSlice.actions
export default goodsSlice.reducer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  • src->index.js
import store from './store'
import { addGoods } from './store/slice/goods'
import { addCar } from './store/slice/car'

const unsubscribe = store.subscribe(()=>{
    console.log(store.getState())
})
store.dispatch(addGoods({
    name:'华为手机',
    price:1999
}))

// unsubscribe()
store.dispatch(addGoods({
    name:'华为电脑',
    price:9990
}))

store.dispatch(addCar(store.getState().goods.goodsList[0]))
store.dispatch(addCar(store.getState().goods.goodsList[0]))
store.dispatch(addCar(store.getState().goods.goodsList[0]))
store.dispatch(addCar(store.getState().goods.goodsList[1]))
store.dispatch(addCar(store.getState().goods.goodsList[1]))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 5. 视图操作添加商品购物车

# React-redux

redux的问题:

需要自己绑定监听来重新渲染整个组件

应该有用到state数据的组件重新render

解决:使用react-redux库

  • 文档: https://react-redux.js.org
  • react-redux是一个react插件
  • 用来简化react中使用 redux
  • 下载: npm i react-redux

# 使用步骤

  1. 下载

    npm i react-redux

  2. 通过Provider 向App及其所有后代组件提供 store

  • src/index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import { Provider } from 'react-redux'
import { BrowserRouter } from 'react-router-dom'
import App from './App.jsx'
import store from './store/index.js'
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render((
    <Provider store={store}>
        <BrowserRouter>
            <App />
        </BrowserRouter>
    </Provider>
))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  • src/App.jsx 组件中如何使用 react-redux ?
import React from 'react'
import { changeNum,asyncChange } from './store/slice/counter'

// useSelector 获取redux中的状态 
// useDispatch 获取dispatch函数,派发任务   
import { useSelector, useDispatch } from 'react-redux'
export default function App() {
    // let data = useSelector(函数)
    let data = useSelector(state=>state) // 获取redux中保存的所有状态数据
    //let data = useSelector(state=>state.counter) // 获取counter 切片的状态数据
    // 获取dispatch函数分发任务
    let dispatch = useDispatch()

    return (
        <div>
            <div>count:{data.counter.num}</div>
            <button onClick={()=>dispatch(changeNum(-1))}>-</button>
            <button onClick={()=>dispatch(changeNum(1))}>+</button>
            <button onClick={()=>dispatch(asyncChange(10))}>异步更新</button>
        </div>
    )
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
编辑 (opens new window)
课件-react路由-V6
课件-国际化

← 课件-react路由-V6 课件-国际化→

最近更新
01
课件-react路由-V6
01-22
02
课件-国际化
01-22
03
课件-其他hooks
01-22
更多文章>
Theme by Vdoing | Copyright © 2019-2024 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式