【问题标题】:Component not updating after fetching new array获取新数组后组件未更新
【发布时间】:2021-03-26 02:32:39
【问题描述】:

我是 ReactJS 和一般 JS 的新手。

我有一个表格,其中填充了来自 API 请求的数据。每行都有一个删除按钮,用于删除该特定条目。当您按下删除按钮时,会打开一个模态框,要求您确认操作,如果单击“是”,则 DELETE 请求将传递给 API,会向 API 请求一个新的 GET 请求以检索新更新的元素列表,模态框将关闭您应该会看到更新后的新表格。

或者至少,这就是应该发生的事情。

现在,当我确认删除操作时,模态关闭但表格没有更新,但是如果我刷新页面,表格会显示更新的内容而没有删除的条目,所以除了表格没有之外,一切似乎都正常工作确认后更新。

如果我按 F5 手动刷新页面,此代码有效:

function TableCategory(prop, ref) {
  const [info, setInfo] = useState([]);

  useImperativeHandle(ref, () => {
    return {
      updateTable: () => {
        fetchData();
      },
    };
  });

  useEffect(() => {
    fetchData();
  }, []);

  const fetchData = async () => {
    const response = await getCategoryList(UserService.getUserToken());

    let newArr = [...response.data];
    setInfo(newArr);
  };


现在,如果我尝试在延迟后再次“模拟刷新”运行 fetchData(),它会正常工作,并且在模态关闭后组件会更新,而无需手动刷新页面。我假设我没有按应有的方式处理 ASYNC 行为。

此代码无需手动刷新即可运行:

useImperativeHandle(ref, () => {
    return {
      updateTable: () => {
        fetchData();
        setTimeout(() => {
          fetchData();
        }, 200);
      },
    };
  });

这是执行 API 请求的异步方法:

export function getCategoryList(myToken) {
  return Promise.resolve(axios.get(CATEGORY_ENDPOINT, config(myToken)));
}

如果您还需要查看其他内容,请告诉我,我只发布了我认为与问题相关的内容。

谢谢!

【问题讨论】:

  • useEffect 运行一次(仅在安装组件时)。但是您需要修改 useEffect 以在 Table 每次更新其数据时执行(在您的情况下为 info)。

标签: javascript reactjs asynchronous promise react-hooks


【解决方案1】:

我认为你的问题在这里:

 useEffect(() => {
    fetchData();
  }, []);

这个空数组 tolts 只对刷新一次做出反应,因此请尝试将 props 传递给它。

    useEffect(() => {
    fetchData();
  }, [info]);

应该可以。

仔细观察:https://reactjs.org/docs/hooks-effect.html 在接下来的步骤结束时。

【讨论】:

  • 使用依赖数组中的信息会生成一个无限循环。我相信这是因为 fetchData() 每次都在生成一个新数组,即使内容相同,对象也是不同的。我似乎找不到避免循环的方法。
【解决方案2】:

所以,我想我已经想通了。

原来我处理 Promise 很糟糕。我不是在等待 DELETE 请求承诺解决。我正在请求一个新的“信息”,其中包含与删除之前的数据相同的数据。该代码实际上按预期工作。这就是为什么如果我延迟再次运行 fetchData() 表会更新。

此链接帮助我了解我做错了什么。

https://masteringjs.io/tutorials/fundamentals/promise

我将工作代码留在下面。

此函数发出 DELETE 请求;当它解析时,它会触发一个 GET 请求来更新表 { fetchData() } 的数据并关闭模态:

const closeAndDelete = (id) => {
    deleteCategory(id, getUserToken()).then(() => {
      prop.updateTable();
      prop.closeModal();
    });
  };

这暴露了 updateTable() 函数;并从 API 中获取数据;解决后,它将数据存储在信息状态:

function TableCategory(prop, ref) {
  const [info, setInfo] = useState([]);

  useImperativeHandle(ref, () => {
    return {
      updateTable: () => {
        fetchData();
      },
    };
  });

  useEffect(() => {
    fetchData();
  }, []);

  const fetchData = async () => {
    await getCategoryList(UserService.getUserToken()).then((response) =>
      setInfo(response.data)
    );
  };

//MORE CODE INVOLING RENDERING THE TABLE AND HANDLING THE DATA. NOT RELEVANT TO THE QUESTION//

}

【讨论】:

    【解决方案3】:

    效果挂钩在组件挂载时运行,但在 组件更新。

    因为您传递了空数组[],所以useEffecttable挂载

    时只运行一次

    但是您希望组件更新并且效果再次运行。这就是为什么您可以为效果挂钩提供第二个参数info 以在组件更新时激活它,而不仅仅是为了安装组件。

    useEffect(() => {
        fetchData();
      }, [info]);
    

    【讨论】:

      猜你喜欢
      • 2019-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-09
      • 2021-06-15
      相关资源
      最近更新 更多