Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用shouldComponentUpdate优化react redux组件_Javascript_Reactjs_React Redux - Fatal编程技术网

Javascript 使用shouldComponentUpdate优化react redux组件

Javascript 使用shouldComponentUpdate优化react redux组件,javascript,reactjs,react-redux,Javascript,Reactjs,React Redux,这是我第一次尝试用react和redux创建一些东西。 所以我的目标是建立一个数据表。我可能会使用一些现有的,但我想用这个挑战自己 该表只显示屏幕上可见的行,您可以显示/隐藏/交换/固定/调整列大小,这样的每个操作也可以将配置文件保存在localstorage中。可以对行进行筛选、编辑和检查,以便对其执行其他操作。 所以这个组件非常全面,有很多特性。 我基本上已经做到了,而且很有效 但我使用了redux,并且,通过在线跟踪任何示例,他们说每个“逻辑”组件都要连接一个组件 所以我做到了-我有一个整

这是我第一次尝试用react和redux创建一些东西。 所以我的目标是建立一个数据表。我可能会使用一些现有的,但我想用这个挑战自己

该表只显示屏幕上可见的行,您可以显示/隐藏/交换/固定/调整列大小,这样的每个操作也可以将配置文件保存在localstorage中。可以对行进行筛选、编辑和检查,以便对其执行其他操作。 所以这个组件非常全面,有很多特性。 我基本上已经做到了,而且很有效

但我使用了redux,并且,通过在线跟踪任何示例,他们说每个“逻辑”组件都要连接一个组件

所以我做到了-我有一个整张桌子的减速器。但直到现在,我才注意到严重的滞后

当我尝试在1个过滤器输入中输入aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

输入单元相当简单-

<input ref={el => this.input = el} className="form-control" type="text" value={this.props.value} onChange={this.handleChange} />
减速器也是一个简单的减速器

case types.ON_FILTER_INPUT_CHANGE: {
    const spec = {
        currentFilter: {
            [action.params.fieldName]: { $set: action.params.value }
        }
    };
    return update(state, spec);
}
Chrome Performance tool将这件可怕的事情记录为:

从例子中,许多人说:

React redux仅重新呈现更改的内容

但事实并非如此。它为组件中的所有内容调用render,这就是为什么我的表工作得如此缓慢的原因。 我没有向任何组件添加shouldComponentUpdate

我的问题是:如何让它工作得更快

将它添加到我的所有组件中会使它变得更好吗

shouldComponentUpdate(newProps, newState) {
    let keys = Object.keys(this.props);
    let result = false;
    for (let i = 0; i < keys.length; i++) {
        if (this.props[keys[i]] !== newProps[keys[i]]) {
            result = true;
            break;
        }
    }
    return result;
}
这似乎使它更具响应性


但在此之前,我对redux有过怀疑——将所有状态存储在一个原子中。

这是一个有点复杂的问题,但值得付出努力。我前面提到的一些要点:

除此之外

1仅当React perf显示较少的渲染时,才使用shouldComponentUpdate/React.PureComponent,否则应用程序可能会出现难以调试的错误

2对于获得更多rendersV DOM渲染的组件,使用componentWillUpdate通过区分新旧道具和状态来检查原因。尝试先减少父组件的渲染,然后移向子组件,就像父组件渲染一样,子组件肯定会渲染,无论其道具或状态是否更改

3使用去抖动onchange处理程序

4虽然很容易,但如果您可以按批处理您的操作,将会注意到非常好的改进


请记住,react始终运行其扩散算法,并在每次渲染时生成新的V-DOM,无论物理DOM是否更改。您可以使用我的指针帮助减少这些渲染。

尽管您说我应该避免使用shouldComponentUpdate/React.PureComponent,但这是防止渲染调用您的第二点的唯一方法,不是吗?如果没有它们,它将为组件的所有DOM树中的所有组件调用render。因此,这是限制渲染调用的唯一方法。我想我没有地方可以让批处理操作调用受益。有很多方法可以防止渲染。当父级渲染或此组件的属性/状态更改时,将发生渲染。通过放置componentWillUpdate挂钩并比较上一个和下一个道具/状态,您可以发现道具/状态是否发生了变化。如果没有更改,则移动到其父级,右上推根,以查找哪个父级是渲染的根本原因。在找到use后,应该只在那里更新组件,但是很多时候道具会因为我们向子级发送新的空对象或新的绑定函数而发生更改,如果找到,请首先更正。而且每个操作都会导致整个树的渲染。当您键入时,许多操作在非常短的时间内被调度,相当于许多渲染,因此会注意到延迟。如果你批量操作,对于批量操作,只会发生1次渲染,就像在键入中一样。请阅读我的链接答案,因为我在那里也提到了所有这些。我正在将整个reducer store对象传递给顶级组件。我想这是一个很大的禁忌,因为它会随着每一件事情的改变而改变。
shouldComponentUpdate(newProps, newState) {
    let keys = Object.keys(this.props);
    let result = false;
    for (let i = 0; i < keys.length; i++) {
        if (this.props[keys[i]] !== newProps[keys[i]]) {
            result = true;
            break;
        }
    }
    return result;
}