如何避免无用的 mapStateToProps()?
How to avoid useless mapStateToProps()?
假设一个 React + Redux 应用程序的页面包含 ~100 MUI checkboxes.
所有这些都是使用 Redux 状态控制的,如下所示:
let CheckboxComponent = React.createClass({
shouldComponentUpdate(nextProps) {
return nextProps.activeList !== this.props.activeList;
}
render() {
let isChecked = this.props.activeList.indexOf(this.props.myId) >= 0;
return <Checkbox
checked={isChecked}
/>;
}
});
function mapStateToProps(state) {
return {
activeList: state.form.myForm.values.activeList;
};
}
CheckboxComponent = connect(mapStateToProps)(CheckboxComponent);
现在,假设我在同一页面上也有一个受控的 <input>
,使用相同的 Redux 存储。输入中的每个按键都会导致 Redux 状态更改。因此,虽然键入此内容会导致许多更改,但不会 activeList
.
我担心的是 - 如果我没记错的话 - mapStateToProps
因此每个 <CheckboxComponent>
的 shouldComponentUpdate
在每次击键时都会被调用 - 那是几百个无用的函数调用.
幸运的是,shouldComponentUpdate
将避免无用的重新渲染,但实际上我的 shouldComponentUpdate
更复杂,因此稍微昂贵(即使比重新渲染便宜)。
如果 mapStateToProps()
不会为 不 涉及 activeList
.
的 Redux 状态更改调用,那么所有问题都可以解决
是否可以通过某种方式进行这样的优化?
这个问题有几个不同的答案。
首先:不,您无法避免 mapState
调用 "aren't affected" 的连接组件。根据定义,Redux 只有一个事件发射器,并且不会跟踪状态的哪些部分 可能 在调度期间发生了变化。由每个单独的订阅者检查新状态并查看是否有相关更改。
其次:是的,为每个单独的击键分派一个单独的操作并不是特别有效。我已经在我自己的应用程序中通过编写一个高阶组件来处理这个问题,该组件使用其状态来缓冲更改以更快地重新呈现输入,同时消除动作调度的抖动。我有 that component available in a gist - made a couple updates since then, but that's the general idea. You may also want to look at libraries such as React-Reformed, React-Form, or React-Redux-Form,它提供了一些类似的部分,可能比我的代码投入了更多的工作。
第三:看起来您正在将一个 "active" 项数组传递给每个单独的复选框组件,并比较该组件内的索引。这不是一个非常高效的模式。更好的方法可能是让父组件拥有一个 ID 列表,将一个 ID 传递给每个连接的子组件,并让每个子组件通过其 mapState
中的 ID 查找自己的数据。请参阅 High-Performance Redux for more information. I also have other info on Redux Performance as part of my React/Redux links list 上的这些幻灯片。
假设一个 React + Redux 应用程序的页面包含 ~100 MUI checkboxes.
所有这些都是使用 Redux 状态控制的,如下所示:
let CheckboxComponent = React.createClass({
shouldComponentUpdate(nextProps) {
return nextProps.activeList !== this.props.activeList;
}
render() {
let isChecked = this.props.activeList.indexOf(this.props.myId) >= 0;
return <Checkbox
checked={isChecked}
/>;
}
});
function mapStateToProps(state) {
return {
activeList: state.form.myForm.values.activeList;
};
}
CheckboxComponent = connect(mapStateToProps)(CheckboxComponent);
现在,假设我在同一页面上也有一个受控的 <input>
,使用相同的 Redux 存储。输入中的每个按键都会导致 Redux 状态更改。因此,虽然键入此内容会导致许多更改,但不会 activeList
.
我担心的是 - 如果我没记错的话 - mapStateToProps
因此每个 <CheckboxComponent>
的 shouldComponentUpdate
在每次击键时都会被调用 - 那是几百个无用的函数调用.
幸运的是,shouldComponentUpdate
将避免无用的重新渲染,但实际上我的 shouldComponentUpdate
更复杂,因此稍微昂贵(即使比重新渲染便宜)。
如果 mapStateToProps()
不会为 不 涉及 activeList
.
是否可以通过某种方式进行这样的优化?
这个问题有几个不同的答案。
首先:不,您无法避免 mapState
调用 "aren't affected" 的连接组件。根据定义,Redux 只有一个事件发射器,并且不会跟踪状态的哪些部分 可能 在调度期间发生了变化。由每个单独的订阅者检查新状态并查看是否有相关更改。
其次:是的,为每个单独的击键分派一个单独的操作并不是特别有效。我已经在我自己的应用程序中通过编写一个高阶组件来处理这个问题,该组件使用其状态来缓冲更改以更快地重新呈现输入,同时消除动作调度的抖动。我有 that component available in a gist - made a couple updates since then, but that's the general idea. You may also want to look at libraries such as React-Reformed, React-Form, or React-Redux-Form,它提供了一些类似的部分,可能比我的代码投入了更多的工作。
第三:看起来您正在将一个 "active" 项数组传递给每个单独的复选框组件,并比较该组件内的索引。这不是一个非常高效的模式。更好的方法可能是让父组件拥有一个 ID 列表,将一个 ID 传递给每个连接的子组件,并让每个子组件通过其 mapState
中的 ID 查找自己的数据。请参阅 High-Performance Redux for more information. I also have other info on Redux Performance as part of my React/Redux links list 上的这些幻灯片。