在react中使用redux toolkit(RTK)写了一个slice, 结果报错:Uncaught TypeError: Cannot perform 'set' on a proxy that has been revoked
看起来原因似乎是在reducer中使用了setTimeout函数的缘故
查看了chatGpt给出的解释:
在 Redux Toolkit 的
createSlice
中,reducers 中的每个 reducer 函数都应该是纯函数,也就是说它们不应该有任何副作用。在你的getLoading
reducer 中,你使用了setTimeout
来延迟修改状态,这违反了纯函数的原则,因此可能导致错误。要解决这个问题,你可以将副作用移到 Redux 中间件中,而不是在 reducer 中进行。例如,你可以使用 Redux Thunk 中间件来处理异步操作,以及在操作完成后分发一个 action 来修改状态。
首先,确保你已经安装了 Redux Thunk 中间件:
换句话说: reducer中不能有setTimeout这样的副作用函数,下面的写法是错误的:
解决办法: 把setTimeout移到redux Thunk中间件来处理,然后使用extraReducers更新state:
首先安装redux thunk: yarn add redux-thunk@2.4.1
然后更新代码如下:
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
interface UserState {
userInfo: Object;
loading: string | null
}
// 把setTimeout移入到createAsyncThunk中间件异步函数中处理
export const getLoading = createAsyncThunk(
"user/getLoading",
async ( thunkAPI) => {
setTimeout(() => {
}, 500);
return "页面加载完毕";
}
);;
export const userSlice = createSlice({
name: "user",
initialState,
reducers: {
},
extraReducers: {
// 在这里通过getLoading的返回值更新state.loading的值
[getLoading.fulfilled.type]: (state, action) => {
state.loading = action.payload;
},
},
});
然后再dispatch派发的时候,一定不能通过dispatch.actions来派发,否则会报错:
Uncaught TypeError: userSlice.actions.getLoading is not a function
而应该通过解构的方式获取函数名,然后再通过dispatch(函数名() )的方式来派发!