componentDidUpdate警告:已安排级联更新

时间:2019-11-12 16:01:50

标签: javascript reactjs

我对React组件有问题,该组件呈现多部分表单并通过API生成结果。

当用户通过表单字段选择项目时,结果会实时更新,并且表单字段本身也会更新以删除不适用的选项。

我的API调用在componentDidUpdate中进行。我首先检查是否是已更新的表单,不是结果或其他任何内容。然后,我进行API调用并更新结果状态和新的字段值。 (没有没有无限循环!我对此很确定。)

这在Firefox和Safari中效果很好。问题似乎出在Chrome浏览器中,其中API后调用setState大约需要4秒钟的时间(使用Chrome的性能工具,这在很大程度上似乎是"componentDidUpdate Warning: Scheduled a cascading update"的结果。)

我不明白的是:

  • 它确实从componentDidUpdate内部更新状态,但是仅一次(对选定值的第一次更改会触发一个状态更改; API结果是第二个状态更改)。当然这不是问题吗?
  • 如果有问题,为什么在Firefox和Safari中没有问题?
  • 我有另一种表单,它们的代码基本相同,只是字段和选项更少,没有相同的问题。

当向组件的状态写入大量数据时,似乎会发生此错误-在这种情况下约为400k。而且,当然,仅在Chrome中。

我尝试到处寻找,而我所看到的只是关于无限循环的东西……这不是这里的问题。有什么建议或类似的经验吗?


更新:

  • 在不同的机器/浏览器上进行了更多测试。 Windows和Mac上的Chrome和Opera中似乎都出现了问题;但在Windows或Mac上的Firefox或Safari中,不是
  • 我尝试在数据较少(因此API加载的数据较少)的测试数据库上运行应用程序,并且即使在Chrome中也不会不会出现问题。尝试在Chrome中执行大型setState似乎是一个非常具体的问题。

本应包含一些代码……这里显然遗漏了很多;这似乎是问题所在。

    componentDidUpdate(prevProps, prevState) {

        if (this.state.results === prevState.results) {
            this.updateSearchParams();
            fetch(`/api/stories-in-text/search/?`+this.getSearchParams())
            .then(response => response.json())
            .then(json => {

                this.setState(
                    {
                        results: json.result,
                        theme_options: json.themes,
                        titles_options: json.titles,
                        textual_collections_options: json.textual_collections,
                        characters_in_story_body_options: json.characters_in_story_body,
                        characters_in_frame_options: json.characters_in_frame,
                        places_in_story_body_options: json.places_in_story_body,
                        places_in_frame_options: json.places_in_frame,
                        component_has_data: true,   
                    }
                );


            });
        }

    }

1 个答案:

答案 0 :(得分:0)

根据link-Gaearon,警告表示警告内容:您计划了级联更新。 “级联”是指更新内部的更新。 React首先通过调用render来协调树,然后提交DOM更改,然后调用生命周期挂钩。如果在componentDidMount中调用setState,则会导致React重复该循环:协调树,提交DOM更改并调用钩子。这很浪费。

您还可以获得更多信息here