简体   繁体   English

在 Redux Reducer 或组件的 ShouldComponentUpdate 中进行深度比较?

[英]Deep Compare in Redux Reducer or in Component's ShouldComponentUpdate?

In my React Redux app, a setInterval() continuously calls an action creater this.props.getLatestNews() which queries a REST API endpoint.在我的 React Redux 应用程序中, setInterval()不断调用操作this.props.getLatestNews()来查询 REST ZDB974238714CA8DE634A7CE1D083A14F 端点。 On getting the API response (an array of objects), it will dispatch an action with the response array as the payload.在获得 API 响应(对象数组)后,它将以响应数组作为有效负载分派一个动作。

React Component反应组件

class Newsfeed extends Component {
    constructor(props) {
        super(props);
        this.state = { ... }
    }

    componentWillMount() {
        this.updateTimer = setInterval(() => { this.props.getLatestNews() }, 1000);
    }

    componentWillUnmount() {
        clearInterval( this.updateTimer );
    }

    shouldComponentUpdate(nextProps, nextState) {
        // Should we do a deep compare of nextProps & this.props, 
        // shallow compare of nextState & thisState?
    }

    render() {
        return ( ... )
    }
}

const mapStateToProps = (state) => ({
    newsfeed: state.newsfeed
});

const mapDispatchToProps = (dispatch) => {
    return {
        getLatestNews: () => dispatch(getLatestNews())
    }
};

export default connect(mapStateToProps, mapDispatchToProps)(Newsfeed);

In the reducer, it currently always update part of the state, whether or not there is any changes在reducer中,目前一直更新部分state,不管有没有变化

Reducer减速器

export default function newsfeedReducer(state=initialState, action) {
    switch (action.type) {
        case NEWSFEED_RECEIVED:
            // Or should we do the deep compare of `action.payload` with `state.items` here?
            return { ...state, items: action.payload }

        default:
            return state
    }
}

Root Reducer根减速器

...

const rootReducer = combineReducers({
    newsfeed: newsfeedReducer
});

...

Most of the time, when the API results are received, there are no new items that do not already exist in the Redux store.大多数情况下,当收到 API 结果时,Redux 存储中没有不存在的新项目。 If the reducer still replaces this part of the store with the API results, the connected component will re-render due to the new object reference to props unless we do a deep comparison inside shouldComponentUpdate() .如果 reducer 仍然用 API 结果替换 store 的这一部分,则连接的组件将由于新的 object 对props的引用而重新渲染,除非我们在shouldComponentUpdate()中进行深入比较。

In order to avoid unnecessary re-rendering of the React Components, I was thinking of either performing a deep compare of the current and next props in the shouldComponentMount() function, or doing the deep compare of the action.payload with state.items that it should replace.为了避免对 React 组件进行不必要的重新渲染,我正在考虑对shouldComponentMount() function 中的当前和下一个道具进行深度比较,或者对action.payloadstate.items进行深度比较它应该替换。

Where is the recommended location to perform the deep comparison?进行深度比较的推荐位置在哪里? Or is this unnecessary at all?或者这根本没有必要?

Thank you!谢谢!

In general, there are few choices we can make to avoid re-rendering when using redux.通常,在使用 redux 时,我们可以做的选择很少,以避免重新渲染。

  1. In Reducer: Do comparison of current state and api/action payload results ie your would-be/next state.在 Reducer 中:比较当前的 state 和 api/action 有效负载结果,即您的可能/下一个 state。 Just return previous state in your reducer to not cause re-render只需在减速器中返回以前的 state就不会导致重新渲染
  2. In component : If your comparison depends on your component prop then use shouldComponentUpdate which gives you nextProps and nextState as arguments.在组件中:如果您的比较取决于您的组件道具,则使用shouldComponentUpdate它将为您提供nextPropsnextState作为 arguments。
  3. In Actions : If you want do conditional dispatching (ie if not happy with api-results then dispatch something else)then do the comparison in your actions.在 Actions 中:如果您想进行条件调度(即,如果对 api-results 不满意,则调度其他内容)然后在您的操作中进行比较。 You can use getState to access the current state.您可以使用getState访问当前的 state。

Note - Even if you use Pure component, the component will still re-render because the state's object reference is changed even if object values are same.注意 - 即使您使用纯组件,组件仍将重新渲染,因为即使 object 值相同,状态的 object 参考也会更改。

Demo of point 1 - shouldComponentUpdate第 1 点的演示 - shouldComponentUpdate

编辑 shouldcomponent 更新修复

Demo of point 2 - state-reducer-etc第 2 点的演示 - state-reducer-etc

编辑 react+redux+reducer+test

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM