2
votes

I have react-redux component SideBar.js which is subscribing to slice of redux state. When the redux state changes, this component gets re-rendered unnecessarily even it does not subscribe to that changing state in redux. Since my state is nested, i do not want to do deep comparisons in shouldComponentUpdate() to avoid re-rendering ... how can i avoid extra re-rendering ?

const mapStateToProps = (state) => {
    return {
        guestLogin:{
            status : state.guestLogin.status,
            marketPlace:state.guestLogin.marketPlace,
            newsFeed:state.guestLogin.newsFeed
        },
        accountLogin:{
            showMemberPosts:state.accountLogin.showMemberPosts,
            newsFeed: state.accountLogin.newsFeed,
            marketPlace:state.accountLogin.marketPlace,
            userInfo:state.accountLogin.userInfo
        },
        marketPlace:{
            reset:state.marketPlace.reset,
            disableFilters:state.marketPlace.disableFilters,
            filters:state.marketPlace.filters,


        }

    };
};

const mapDispatchToProps = dispatch => {
    return {
        guestMarketPlaceClickHandler :()=>{dispatch(marketPlaceCLickHandlerDispatcher())},
        guestNewsFeedClickHandler:()=>{dispatch(newsFeedClickHandlerDispatcher())},
        memberMarketPlaceClickHandler:()=>{dispatch(marketPlaceCLickHandlerDispatcher())},
        memberNewsFeedClickHandler:()=>{dispatch(newsFeedClickHandlerDispatcher())},
        myPostsClickHandler:()=>{dispatch(myPostsClickHandlerDispatcher());},
        dispatch:(action)=>{dispatch(action)}
    }
};

export default connect(mapStateToProps,mapDispatchToProps)((SideBar));
1
There is no other way unfortunately. Try to minimize the number of deep comparisons needed to check if the component needs to be rerendered. Even deep comparisons are far less costly versus needlessly rerendering a large component. - Shawn Andrews
@ShawnAndrews.... as you can see my slice of state has 10 key value pairs, is it ok to do 10 comparsions in shouldComponentUpdate() ? - Manpreet Singh
can you clarify, what part of state does change for which you dont want your component to re-render? can you gice example for such a slice? - dee zg
@deezg.. for e.g.. initial full state for marketPlace has key value pair - isLoading : false which become isLoading: true during some dispatch... at this dispatch,, my SideBar.js component also gets re-rendered even it is not subscribed to this key value pair in slice of marketPlace state - Manpreet Singh
ten comparisons is reasonable. it is also much better than the alternative of rerendering - Shawn Andrews

1 Answers

4
votes

Connecting your component to redux makes it a PureComponent. That is, it will do a shallow comparison of the props to decide if it needs to re-render. By nesting your store values in mapStateToProps you are guaranteeing that the shallow comparison will fail.

That is, guestLogin: {...} creates a new object for the value of guestLogin every time.

You can either use reselect or an equivalent solution to create selectors which return the same objects while the state doesn't change, or just make your mapStateToProps shallow, eg..

const mapStateToProps = (state) => {
    return {
        glStatus : state.guestLogin.status,
        glMarketPlace:state.guestLogin.marketPlace,
        glNewsFeed:state.guestLogin.newsFeed
        alShowMemberPosts:state.accountLogin.showMemberPosts,
        alNewsFeed: state.accountLogin.newsFeed,
        alMarketPlace:state.accountLogin.marketPlace,
        alUserInfo:state.accountLogin.userInfo
        mpReset:state.marketPlace.reset,
        mpDisableFilters:state.marketPlace.disableFilters,
        mpFilters:state.marketPlace.filters,
    };
};