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>,
)