我对
todos
数组使用了 useState 钩子
const [todos, setTodos] = useState([]); `
我使用这个数组来显示所有待办事项并为其建立索引。我还需要初始安装的待办事项,因此我使用 useEffect 挂钩。 `
useEffect(() => {
const getTodoData = async () => {
const { data } = await axios.get(`${BASE_URL}/todos`);
setTodos(data);
};
getTodoData();
}, [todos]);
但是,上面的代码会生成无限的重新渲染,并对
${BASE_URL}/todos
发出无限的请求。
我明白为什么会发生这种情况。如果我错了,请纠正我,但我认为当我
setTodos(data);
todos
数组发生变化时,即状态发生变化,即 useEffect 钩子 [todos]
中的依赖关系发生变化。因此,设置函数会运行,发出请求,然后再次setTodos(data);
。因此无限循环。
我看到了与此相关的其他帖子,几乎每个人都说只需删除依赖项即可。但我不明白的是,如果我们要删除依赖项,那么在创建新的待办事项后,我们将必须刷新页面才能看到反映的更改。我认为这不可行。
如果有办法让新的待办事项不刷新就出现在页面上,请帮助我
您对无限循环发生原因的理解绝对正确。出现这个问题是因为
todos
数组作为依赖项包含在 useEffect
钩子中,因此每次调用 setTodos
时,todos 状态都会发生变化,再次触发 useEffect
,从而导致无限重新渲染。
从依赖数组中删除todos:为了在初始挂载时获取数据,只需要一个空的依赖数组[],这样效果在组件挂载时只运行一次。
无需刷新即可处理新待办事项:要在无需刷新页面的情况下处理新待办事项的添加,您应该在创建新待办事项后直接更新待办事项状态。这样,新的待办事项将立即显示。
以下是调整代码的方法:
import { useState, useEffect } from 'react';
import axios from 'axios';
const TodosComponent = () => {
const [todos, setTodos] = useState([]);
useEffect(() => {
const getTodoData = async () => {
try {
const { data } = await axios.get(`${BASE_URL}/todos`);
setTodos(data);
} catch (error) {
console.error('Error fetching todos:', error);
}
};
getTodoData();
}, []); // Empty array ensures this runs only once on mount
const addTodo = async (newTodo) => {
try {
const { data } = await axios.post(`${BASE_URL}/todos`, newTodo);
setTodos((prevTodos) => [...prevTodos, data]); // Update the state with the new todo
} catch (error) {
console.error('Error adding new todo:', error);
}
};
return (
<div>
{/* Render todos and other UI elements */}
</div>
);
};
export default TodosComponent;
useEffect
具有空依赖项数组:
addTodo
功能:
addTodo
函数处理添加新的待办事项。成功向后端添加新的待办事项后,使用 todos
函数将新的待办事项附加到现有的 setTodos
状态。这使得新的待办事项可以立即反映在 UI 中,而无需刷新页面。如果您需要处理更新或删除,您可以遵循类似的方法,相应地更新
todos
状态:
这种方法可确保您的 UI 与后端数据保持同步,而无需刷新页面。