我有一个更新全局计数器的动作和减速器。此操作将在快速间隔内触发。 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应用于完整状态。不确定是否相关。
答案 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。