【问题标题】:How to avoid re-render in react-redux connected component?如何避免在 react-redux 连接组件中重新渲染?
【发布时间】:2019-04-27 03:45:54
【问题描述】:

我有 react-redux 组件 SideBar.js,它订阅了 redux 状态切片。当 redux 状态发生变化时,这个组件会不必要地重新渲染,即使它没有订阅 redux 中的变化状态。由于我的状态是嵌套的,我不想在 shouldComponentUpdate() 中进行深度比较以避免重新渲染...如何避免额外的重新渲染?

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));

【问题讨论】:

  • 很遗憾,没有别的办法。尽量减少检查组件是否需要重新渲染所需的深度比较次数。与不必要地重新渲染一个大型组件相比,即使是深度比较的成本也要低得多。
  • @ShawnAndrews.... 你可以看到我的状态切片有 10 个键值对,可以在 shouldComponentUpdate() 中进行 10 次比较吗?
  • 你能澄清一下,你不想让你的组件重新渲染的状态部分发生了变化吗?你能举个例子吗?
  • @deezg.. 例如,marketPlace 的初始完整状态具有键值对 - isLoading : false 在某些调度期间变为 isLoading: true ......在这次调度中,我的 SideBar.js 组件也即使在市场状态切片中未订阅此键值对,也会重新渲染
  • 十次比较是合理的。它也比重新渲染的替代方法好得多

标签: reactjs redux


【解决方案1】:

将您的组件连接到 redux 使其成为 PureComponent。也就是说,它将对道具进行浅层比较,以决定是否需要重新渲染。通过将您的商店值嵌套在 mapStateToProps 中,您可以保证浅层比较会失败。

guestLogin: {...}每次都会为guestLogin的值创建一个新对象。

您可以使用reselect 或等效的解决方案来创建选择器,这些选择器在状态不变的情况下返回相同的对象,或者只是让您的 mapStateToProps 变浅,例如......

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,
    };
};

【讨论】:

  • 感谢您的帮助...您认为我是否可以将减速器分解为更细粒度的状态...这会有所帮助吗?
  • reducers 并没有真正参与其中。在将任何操作分派到 store 后,所有 mapStateToProps 函数都将运行并将其结果合并到组件的 props 中。该组件将与之前的道具进行浅层比较并相应地渲染。阻止渲染就是确保那些顶级道具对象不会发生不必要的变化。
猜你喜欢
  • 2020-12-13
  • 1970-01-01
  • 2020-12-21
  • 1970-01-01
  • 2018-03-24
  • 1970-01-01
  • 2021-12-25
  • 1970-01-01
  • 2016-12-06
相关资源
最近更新 更多