reduxjs/toolkit 的学习使用

1、创建cartStore.js模块(同步方法的调用)

javascript 复制代码
// 1. 从 @reduxjs/toolkit 库中导入 createSlice 函数
// createSlice 是 RTK 的核心函数,用于快速创建 Redux 的 reducer 和 action
import { createSlice } from "@reduxjs/toolkit"

// 2. 调用 createSlice 函数,创建一个名为 cart 的切片(Slice)
const cartSotre = createSlice({
    // 3. name 字段:定义 Slice 的名称(核心作用:作为 action type 的前缀)
    // 比如 increase 动作的 type 会自动生成为 "cart/increase",避免不同模块 action 重名
    name:'cart',
    
    // 4. initialState 字段:存储该模块的所有状态  定义该 Slice 的初始状态
    initialState:{
        count:0 // 购物车数量,初始值为 0
    },
    
    // 5. reducers 字段:定义该模块的同步状态更新规则(核心)
    reducers:{
        // 5.1 定义 increase 动作的 reducer 函数:实现 count 加 1
        increase(state){
            state.count++ 
        },
        
        // 5.2 定义 decrease 动作的 reducer 函数:实现 count 减 1
        decrease(state){
            state.count--
        },
        
        // 5.3 定义 addToNum 动作的 reducer 函数:设置 count 为指定值
        // 参数 action:触发该动作时传入的 "动作对象",包含 payload(负载,即传递的数据)
        addToNum(state,action){
            // action.payload 是调用该动作时传入的参数(比如想把 count 设为 10,payload 就是 10)
            state.count = action.payload
        }
    }
})

// 6. 导出自动生成的 action creator(动作创建函数)
// cartSotre.actions 是 createSlice 自动根据 reducers 里的函数名生成的
export const {increase,decrease,addToNum} = cartSotre.actions

// 7. 导出该 Slice 的 reducer 函数(供全局 store 注册)
// cartSotre.reducer 是 createSlice 自动整合所有 reducers 函数生成的最终 reducer
export default cartSotre.reducer

2、创建userStore.js模块,(异步方法的调用)

javascript 复制代码
import { createSlice ,createAsyncThunk } from "@reduxjs/toolkit"
const userStore = createSlice({
    name:'user',
    initialState:{
        userInfo:{},
        otherUserInfo:{}
    },
    reducers:{
        upUserInfo(state,action){
            state.userInfo = action.payload
        },
        upOtherUserInfo(state,action){
            state.otherUserInfo = action.payload
        }
    }
})

// 异步请求方式一
export const fetchUserInfo = ()=>{
    return async (dispatch)=>{ 
        // 模拟接口请求
        // const res = await axios.get(url) 
        const res = {name:'wtj',age:11} 
        dispatch(upUserInfo(res))
    }
}


// 异步请求方式二
// 1. 定义异步 action(只处理成功,不捕获错误)
// 第一个参数:action 类型前缀(模块名/动作名) 基本上是固定写法
// 第二个参数:异步函数(接收参数,返回接口数据)
export const otherFetchUserInfo = createAsyncThunk(
  'user/oetherFetchUserInfo',  // 类型前缀(模块名/动作名)
  async (userId,{dispatch}) => { // 接收组件传入的 userId 参数
    // 模拟接口请求(替换为你的真实接口)
    // const response = await fetch(`/api/user/${userId}`);
    // return data
    dispatch(upOtherUserInfo({name:'香织',age:38}))  ; // 成功数据传给 fulfilled 状态的 payload
  }
);

export const {upUserInfo,upOtherUserInfo} = userStore.actions
export default userStore.reducer

3、创建index.js, 在index中注册cartStore、userStore模块

javascript 复制代码
import { configureStore } from "@reduxjs/toolkit"
import cartReducer  from "./modules/cartStore.js"
import userReducer  from "./modules/userStore.js"

const store = configureStore({
    reducer:{
        cart:cartReducer,
        user:userReducer
    }
})

export default store

4、在组建中使用

javascript 复制代码
import { useSelector,useDispatch } from "react-redux"
import { increase,decrease,addToNum } from "./store/modules/cartStore.js"
import {  fetchUserInfo,otherFetchUserInfo } from "./store/modules/userStore.js"
import { useEffect } from "react";

const App = () => {
// dispatch 是触发所有 action(同步/异步)的核心方法,调用 dispatch(action) 即可更新 Store 状态
  const dispatch = useDispatch();

// 解构赋值:从 state.cart 中取出 count 状态(对应 cartStore 的 initialState.count)
  const {count} = useSelector(state=>state.cart)

// 从 state.user 中取出 userInfo 和 otherUserInfo(对应 userStore 中存储的两个用户信息)
  const {userInfo,otherUserInfo} = useSelector(state=>state.user)

  // 依赖数组 [dispatch]:dispatch 是稳定的,因此该 useEffect 仅在组件挂载时执行一次
  useEffect(()=>{
    // 触发第一个异步 action:无参数请求用户信息
    // dispatch 调用 fetchUserInfo() 生成的异步 action,触发 userStore 中的异步请求逻辑
    dispatch(fetchUserInfo())
    // 触发第二个异步 action:传入参数 1 请求另一个用户信息
    // otherFetchUserInfo(1) 会把 1 作为参数传给异步 thunk 函数,实现带参请求
    dispatch(otherFetchUserInfo(1))
  },[dispatch])

  return <>
    <div>{userInfo.name}</div>
    <div>{otherUserInfo.name}</div>
    <button style={{ fontSize:'20px'}} onClick={()=>dispatch(increase())}>+</button>
    {count}
    <button style={{ fontSize:'20px'}} onClick={()=>{dispatch(decrease())}}>-</button>
    <button style={{ fontSize:'20px'}} onClick={()=>{dispatch(addToNum(20))}}>赋值20</button>
  </>
}


export default App

5、在入口文件,用Provider 包裹根组件,实现store的参数传递

javascript 复制代码
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'
import { Provider } from "react-redux"
import store from "./store"

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <Provider store={store}>
      <App />
    </Provider>  
  </StrictMode>,
)
相关推荐
陈随易15 小时前
Postman 被曝自动往 Claude Code 和 Codex 装插件
前端·后端·程序员
Dream-Y.ocean17 小时前
鸿蒙PC平台宅匠 3D 室内设计适配实战:基于 Electron 壳方案的 Three.js 双渲染引擎与参数化户型编辑器开发
javascript·3d·harmonyos
Csvn18 小时前
性能监控
前端
Highcharts.js18 小时前
Highcharts Gantt使用符号的自定义数据标签开发甘特图示例
javascript·甘特图·highcharts·图表开发·实战代码·响应式图表
前进的李工18 小时前
Agent 学习笔记 05:系统提示词应该怎么写
笔记·学习·prompt·agent·个人开发·few-shot·ai应用开发
Csvn18 小时前
构建工具
前端
FRing0319 小时前
vue2干货总结3(computed计算属性、watch监听器)
开发语言·前端·vue.js·vue2
正在走向自律20 小时前
【3/5】人工智能训练师 三级/高级工 考证学习方向:从“独立执行”到“设计、归因与全链条负责”
人工智能·学习·人工智能训练师·注方案设计·数据质控负责人·模型评测与调优辅助·ai训练项目交付
kyriewen21 小时前
Skills 榜前 10 我全装了:只有 3 个能直接用
前端·javascript·程序员
IT_陈寒21 小时前
当Java的hashCode遇上Lombok,我的缓存被全清了
前端·人工智能·后端