如何限制react-redux连接更新重新渲染到特定的状态分支?

时间:2017-12-29 04:05:33

标签: javascript reactjs redux react-redux rendering

我有一个更新全局计数器的动作和减速器。此操作将在快速间隔内触发。 reducer为每个动作返回一个新的状态副本。减速器看起来像:

import { handleActions } from 'redux-actions';
import { sceneTick } from './actions';

export default (state, action) => handleActions({
  [sceneTick]: (state, action) => {
    return {
      ...state,
      loop: action.payload,
    }
  },

我在各种React组件上使用react-redux' connect方法。并非所有组件都关心此循环计数器。因为我在每个tick上都在reducer中返回一个新状态,所有订阅connect的组件都会执行mapDispatchToProps,这会导致不必要的React渲染调用。

其中一个组件如下:

const mapStateToProps = (state, props) => {
  return {
    viewport: state.viewport,
    assets: state.assets,
  };
};


export default connect(mapStateToProps, {})(Component)

即使此组件不依赖state.loop,它也会被触发重新渲染。这会导致在不需要重新渲染的组件中重新渲染,重叠渲染,多次渲染,不必要的渲染,性能问题和意外行为。

更新 我还应该在这里使用combineReducers添加,并将所有reducers应用于完整状态。不确定是否相关。

3 个答案:

答案 0 :(得分:6)

根据Redux实现,connect是纯粹的,因此对它需要提供给组件的道具进行浅层比较,即它在其实现中实现了shouldComponentUpdate方法并且不会触发如果从mapStateToProps返回的数据没有更改,则重新呈现连接的组件。

Redux监控每次更改的状态更改非常重要,因为只有它才能决定是否更新。

由于Pure组件对状态和道具进行浅层比较,因此应确保您的状态不是高度嵌套的

答案 1 :(得分:2)

Redux connect接受areStatesEqual函数选项,该选项可用于将等式检查缩小到特定的状态分支。

export default connect(
  {},
  {},
  null,
  {
    areStatesEqual: (next, prev) => {
      return (
        prev.branch === next.branch
      );
    }
  }
)(Component);

答案 2 :(得分:0)

如果由于redux而导致性能问题,请使用react shouldComponentUpdate方法。

https://reactjs.org/docs/react-component.html#shouldcomponentupdate

更新:CombineReducers会有所作为。尝试更改

return {
   ...state,
   loop: action.payload,
}

state.loop = ...action.payload;
return state;

如果你不想改变状态,你应该使用combineReducer和loop作为自己的reducer。由于您没有使用combineReducers,我将状态转换为rootReducer。它类似于redux作者使用combineReducers(video)所做的,除了在combineReducer中创建了nextState。