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>,
)
相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
一隅论数智3 天前
给AI一张“业务概念地图“:本体如何从哲学走向企业智能
大数据·人工智能·经验分享·笔记·学习·学习方法·政务
XiHongShi20163 天前
STM32F407 RTC定时器例程,建议保存
stm32·单片机·学习
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
爱吃苹果的日记本3 天前
离散数学第六课
学习·离散数学
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js