如何在Redux Toolkit的createSlice的prepare方法中发起异步请求?
结论
prepare 方法不能用于发起异步调用,它必须是纯同步函数。
Redux Toolkit 中 createSlice 的 prepare 回调设计用途是同步预处理 action 的 payload、meta 等字段,比如添加唯一ID、格式化参数等,调用 action creator 时会同步执行prepare、立刻返回标准action对象,随后直接派发给reducer。你为prepare添加async声明后,函数返回的是Promise实例而非标准action结构,因此reducer执行时异步请求还未返回,自然拿不到payload值。
符合你诉求的实现方案
你可以使用RTK内置的createAsyncThunk定义异步逻辑,再通过createSlice的extraReducers字段处理异步请求的不同状态,所有逻辑完全可以写在同一个slice文件内,不需要拆分到独立文件,完全符合你提升可维护性的诉求。
示例代码如下:
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit' import axios from 'axios' // 异步登录逻辑,和slice定义在同一个文件 export const loginToConsole = createAsyncThunk( 'auth/loginToConsole', async (credentials) => { const response = await axios.post( `${apiEndPoint}/api/auth/login`, credentials ) return response.data } ) const initialState = { isLoggedIn: false, loading: false, error: null } export const authReducers = createSlice({ name: "auth", initialState, reducers: { // 其他同步reducer可以继续写在这里 }, extraReducers: (builder) => { builder // 处理请求发起中状态 .addCase(loginToConsole.pending, (state) => { state.loading = true state.error = null }) // 处理请求成功状态 .addCase(loginToConsole.fulfilled, (state, action) => { console.log("Reducer Called", action); state.loading = false state.isLoggedIn = true // 可以直接取到接口返回的payload state.userInfo = action.payload }) // 处理请求失败状态 .addCase(loginToConsole.rejected, (state, action) => { state.loading = false state.error = action.error.message }) } })
内容的提问来源于stack exchange,提问作者Mahesh Kumaran
相关产品推荐
相关产品推荐

