您不希望您的 getBasketballTeam 函数直接通过 store.getState() 访问商店。
你想要的是一个“thunk”动作创建者,当你dispatch它时,它会获取商店实例作为参数。
你想要的流程是这样的:
- 组件通过
useSelector(或connect)持续监听篮球队状态。
- 组件安装。
- 组件调度
getBasketballTeam 操作。
- 操作从 API 获取数据。
- Reducer 将数据从操作保存到状态。
- 状态更新。
- 组件使用状态中的新数据重新渲染。
最简单的方法是使用 Redux Toolkit 中的 createAsyncThunk 函数。此帮助程序通过分派单独的错误操作来处理所有错误。试试这样的:
行动:
export const fetchBasketballTeam = createAsyncThunk(
"team/fetchBasketballTeam",
async (_, thunkAPI) => {
const token = thunkAPI.getState().user.token;
if ( ! token ) {
throw new Error("Missing access token.");
}
const res = await fetch(actions.GET_BASKETBALLTEAM, {
method: "GET",
headers: { Authorization: `Bearer ${token}` }
});
if (res.status !== 200) {
throw new Error("Invalid response");
}
// what you return is the payload of the fulfilled action
return res.json();
}
);
减速机:
const initialState = {
status: "idle",
data: null
};
export const teamReducer = createReducer(initialState, (builder) =>
builder
.addCase(fetchBasketballTeam.pending, (state) => {
state.status = "pending";
})
.addCase(fetchBasketballTeam.fulfilled, (state, action) => {
state.status = "fulfilled";
delete state.error;
state.data = action.payload;
})
.addCase(fetchBasketballTeam.rejected, (state, action) => {
state.status = "rejected";
state.error = action.error;
})
);
商店:
export const store = configureStore({
reducer: {
team: teamReducer,
user: userReducer,
}
});
组件:
export const BasketballTeam = () => {
const { data, error, status } = useSelector((state) => state.team);
const dispatch = useDispatch();
useEffect(
() => {
dispatch(fetchBasketballTeam());
},
// run once on mount
// or better: take the token as an argument and re-run if token changes
[dispatch]
);
if (status === "pending") {
return <SomeLoadingComponent />;
}
if (!data) {
return <SomeErrorComponent />;
}
// if we are here then we definitely have data
return <div>{/* do something with data */}</div>;
};