我的React应用程序中有几个页面。每当用户点击页面3时,我都想发送一个获取请求来获取数据并将其设置到存储中。但出于某种原因,Redux Toolkit在应用程序加载和page3加载时也会进行两次调度。因此,每当页面加载或用户在page3和其他页面之间切换时,都会发出两个获取请求。
如何解决?
应用程序.tsx
import { NavLink, Route, Routes } from "react-router-dom";
import "./styles.css";
import Todo from "./Todo";
const App = () => {
const routes = [
{
path: "/",
element: <div className={"page1"}>Page 1</div>
},
{
path: "/page2",
element: <div className={"page2"}>Page 2</div>
},
{
path: "/page3",
element: <Todo />
}
];
return (
<div className="App">
<div className="Navigation">
<NavLink to={"/"}>Page 1</NavLink>
<NavLink to={"/page2"}>Page 2</NavLink>
<NavLink to={"/page3"}>This sends a request</NavLink>
</div>
<div className="Content">
<h2>Content</h2>
<Routes>
{routes.map((route: any) => (
<Route path={route.path} element={route.element} key={route.path} />
))}
</Routes>
</div>
</div>
);
};
export default App;
Todo组件
import { useEffect } from "react";
import { useDispatch } from "react-redux";
import { AppDispatch } from "./store/store";
import { fetchTodo } from "./store/TodoSlice";
const Todo: React.FC = () => {
const dispatch = useDispatch<AppDispatch>();
useEffect(() => {
dispatch(fetchTodo());
}, []);
return <div className={"page3"}>This dispatches twice</div>;
};
export default Todo;
存储切片
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
export interface ICategoryState {
todo: any[];
isLoading: boolean;
}
const initialState: ICategoryState = {
todo: [],
isLoading: false
};
const BASE_URL = "https://jsonplaceholder.typicode.com/todos";
export const fetchTodo = createAsyncThunk("todos/fetchTodo", async () => {
const response = await fetch(BASE_URL);
const data = await response.json();
return data as any[];
});
export const todoSlice = createSlice({
name: "todos",
initialState,
reducers: {},
extraReducers: (builder) => {
builder.addCase(fetchTodo.pending, (state, action) => {
state.isLoading = true;
console.log("Start loading");
});
builder.addCase(fetchTodo.fulfilled, (state, { payload }) => {
state.todo = payload;
state.isLoading = false;
});
builder.addCase(fetchTodo.rejected, (state, { payload }) => {
console.log("Error happened");
state.isLoading = false;
});
}
});
export default todoSlice.reducer;
这里还有一个代码沙盒:https://codesandbox.io/s/ecstatic-cookies-xicjxp?file=/src/App.tsx
默认情况下,CRA会创建在严格模式下运行的应用程序,这会导致带有空依赖项数组的useEffects在加载时运行两次。它应该能帮助人们更好地编写代码。当然,这种情况只发生在开发模式中。只需移除标签
<StrictMode>
在index.tsx中,它将根据需要工作。我已经纠正了你的沙盒。