【问题标题】:Is using setState in every iteration of a loop bad practice?在循环的每次迭代中都使用 setState 是不好的做法吗?
【发布时间】:2020-01-24 20:25:56
【问题描述】:

这是一个小代码sn-p:

async componentDidMount() {
    ...
    this.state.postList.forEach(element => {
      this.fetchItem(element);
    });
}

async fetchItem(query) {
    ...
    this.setState( previousState => {
        const list = [...previousState.data, data];
        return { data: list };
    });
}

我很想知道在forEach 循环的每次迭代中使用setState 是否是个坏主意。我怀疑它会影响性能,但我想确定一下,因为这似乎是解决此问题的最简单方法。

【问题讨论】:

  • 你的 fetchItem() 函数是 async 但对它的调用不包括 await
  • @Pointy 这就是异步的价值!您不必等待!在我看来他想同时提出请求。
  • 当然可以,但效果明显不同。假设所有呼叫在或多或少相同的时间内返回,通过不等待代码正在设置一种情况,即一系列响应都在短时间内调用setState;我认为这是问题的核心。
  • 如果你在做异步的东西,那么最简单的可能是Promise.all(array.map(asyncFunction)).then(result=>this.setState...
  • setState 的调用是批处理的,因此在所有请求同时或几乎同时快速返回的最坏情况下,我认为您的所有调用都将被批处理为一个大更新。我也同意@HMR 关于使用Promise.all 然后对最终结果执行 setState 的观点,但我认为这对于一个小列表来说并不重要

标签: javascript reactjs state


【解决方案1】:

这是另一种方法:更新您的 fetchItem 以仅退回商品。在您的 componentDidMount 中使用 Promise.all 获取所有项目,然后在单个操作中将它们提交到状态。

async componentDidMount() {
    const items = await Promise.all(this.state.postList.map(element => fetchItem(element)));
    this.setState({data: items});
}

async fetchItem(query) {
    const item = await getItem(query) // however you accomplish this
    return item;
}

【讨论】:

    【解决方案2】:

    我很想知道在 forEach 循环的每次迭代中使用 setState 是否是个坏主意。

    如果它直接在迭代中,那么肯定,因为 React 必须合并你在迭代期间所做的所有更新,这可能比你只需要更多的时间设置循环后的状态。 但是,在您的情况下,您确实在每次迭代中启动了一个异步操作,并且由于所有异步任务在不同时间完成,因此更新不会一次全部运行。您的方法的主要好处是,如果这些异步任务需要一些时间(例如,如果您为每个任务获取大量数据),那么已经可以显示一些信息,而有些信息仍在加载中。如果所有这些异步调用只加载少量数据,那么您实际上应该更改您的 API 以一次传送所有数据。所以这真的取决于你的用例是好是坏。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 2013-09-04
      • 2018-10-19
      相关资源
      最近更新 更多