当createAsyncThunk分派事件完成时,useSelector会更新两次



我是redux工具包和react的新手。但我正在努力遵循redux工具包切片器的方法。

我的切片:

import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
const axios = require("axios");
export const fetchR = createAsyncThunk(
"fetchR",
async (teamId) => {
console.log(teamId);
var data = await axios.get(url);
return data.data;
}
);
export const rSlice = createSlice({
name: "slice",
initialState: {
data: { count: 0, data: [] },
loading: "",
},
reducers: {
setR: (state, action) => {},
getR: (state, action) => {},
},
extraReducers: (builder) => {
builder.addCase(fetchR.pending, (state, action) => {
state.loading = "loading";
});
builder.addCase(fetchR.fulfilled, (state, action) => {
state.data = action.payload;
state.loading = "loaded";
});
},
});
// Action creators are generated for each case reducer function
export const { setR, getR } = rSlice.actions;
export default rSlice.reducer;

我的组件调用fetchR createAsyncThunk。

<IconButton
onClick={() => {
dispatch(fetchR("FU"));
}}
type="submit"
sx={{ p: "10px" }}
aria-label="search"
>
<SearchIcon />
</IconButton>

我的组件,用于侦听rSlice的状态更改。

const MainSub = () => {
const rList = useSelector((state) => {
console.log(state.res);
return state.res;
}, shallowEqual);
return (
<div>
</div>
);
};
export default MainSub;

我的控制台日志:

FU
MainSub.js:6 
{res: {…}}
res: {data: {…}, loading: 'loading'}
[[Prototype]]: Object
MainSub.js:6 
{res: {…}}
res: {data: {…}, loading: 'loaded'}
[[Prototype]]: Object
MainSub.js:6 
{res: {…}}
res: {data: {…}, loading: 'loaded'}
[[Prototype]]: Object

请注意,当createAysncThunk调度完成时,MainSub中的控制台日志会运行两次。我不确定是什么原因导致这种情况发生两次查看我的网络流量,只有一个get请求所以我知道我不会提出多个请求。我们的thunk将一个事件发送到挂起并完成一次。但useSelector认为,当Thunk发送到completed时,状态发生了两次更改。这个控制台日志再次出现在我们的MainSub组件中。如有任何帮助,我们将不胜感激。谢谢!

是的,选择器将运行两次-一次是在调度操作本身后在Redux订阅回调中运行(因此它在React的外部运行(,但可能在渲染期间在组件内部再次运行。这是由于useSelector的一个实现细节。

附带说明一下,您永远不应该编写useSelector(state => state)-这将导致在根状态更改时组件总是重新渲染相反,您应该始终选择该组件所需的最小状态。

最新更新