SetState创建重复的条目

时间:2018-01-28 01:50:30

标签: reactjs

我正在尝试生成一组UI控件,因为它们正在呈现,结果状态包含重复的条目。有没有一种好方法可以防止这种情况发生?

每次呈现组件时都会触发此代码。有多个表具有类似的控件,我使用它来获取每个控件的最大行数:

        const newcontrols: LoadedCtrls = {
            "itemCtrlType": controlType,
            "rowsCount": numberRows,
        };
        if (this.state.loadedcontrols.length == 0) {
            this.setState({
                loadedcontrols: [...this.state.loadedcontrols, newcontrols]
            })
        }
        for (var i = 0; i < this.state.loadedcontrols.length; i++) {
            if (this.state.loadedcontrols[i].itemCtrlType == controlType) {
                if (this.state.loadedcontrols[i].rowsCount < numberRows) {
                    this.setState({
                        loadedcontrols: [...this.state.loadedcontrols.slice(0, i), newcontrols, ...this.state.loadedcontrols.slice(i)]
                    })
                }
            }
            else {
                this.setState({
                    loadedcontrols: [...this.state.loadedcontrols, newcontrols]
                })
            }
        }

控制台中的结果如下:

[{"itemCtrlType":"map1","rowsCount":2},{"itemCtrlType":"map2","rowsCount":3},{"itemCtrlType":"location","rowsCount":5},{"itemCtrlType":"map2","rowsCount":3},{"itemCtrlType":"monitor","rowsCount":7},{"itemCtrlType":"monitor","rowsCount":7}]

我试图使用具有不变性的良好实践,但似乎仍然使用重复项启动setState,我知道它是一个异步操作。那么有办法防止这种情况吗?

编辑:每次组件的获取功能输出数据时触发该功能,并在组件中设置状态:

            .then(data => {
            this.setState({
                results: data,
                loading: false,
            }, () => {
                this.finishLoad(this.state.controlType, this.state.customerId, data.length);
            });
        });

1 个答案:

答案 0 :(得分:1)

使用setState()会导致非常不确定的行为;有两个原因:

  1. setState()不应该用作同步调用(即,您依赖于state立即更新)。
  2. 在迭代状态时调用setState()可能没有预期的行为(因为1。)。
  3. 您可能会考虑更一般的模式:

    let localState=this.state;
       // Rely on and modify localState, as desired
    this.setState(localState) // Set final state and trigger potential re-render
    

    您可能不需要在初始setState()调用中指定回调,因为状态更改是批处理的,并且隐式调用下一个呈现。

    以下阅读可能有用setState() State Mutation Operation May Be Synchronous In ReactJS