由于 useEffect hook 导致 React 中无限重新渲染

问题描述 投票:0回答:1

我对

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);
。因此无限循环。

我看到了与此相关的其他帖子,几乎每个人都说只需删除依赖项即可。但我不明白的是,如果我们要删除依赖项,那么在创建新的待办事项后,我们将必须刷新页面才能看到反映的更改。我认为这不可行。

如果有办法让新的待办事项不刷新就出现在页面上,请帮助我

reactjs api react-hooks axios rerender
1个回答
0
投票

您对无限循环发生原因的理解绝对正确。出现这个问题是因为

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;

说明:

  1. useEffect
    具有空依赖项数组:
    • 通过传递一个空数组 [] 作为依赖数组,效果只会在组件首次安装时运行一次。这可以防止无限循环。
  2. addTodo
    功能:
    • addTodo
      函数处理添加新的待办事项。成功向后端添加新的待办事项后,使用
      todos
      函数将新的待办事项附加到现有的
      setTodos
      状态。这使得新的待办事项可以立即反映在 UI 中,而无需刷新页面。

处理更新或删除

如果您需要处理更新或删除,您可以遵循类似的方法,相应地更新

todos
状态:

  • 要更新待办事项,请在状态数组中找到待办事项,修改它,然后使用更新后的数组设置状态。
  • 要删除待办事项,请从状态数组中过滤掉待办事项,并使用过滤后的数组设置状态。

这种方法可确保您的 UI 与后端数据保持同步,而无需刷新页面。

© www.soinside.com 2019 - 2024. All rights reserved.