使用 connect 和 withRouter 包装组件的顺序是不是重要

Posted

技术标签:

【中文标题】使用 connect 和 withRouter 包装组件的顺序是不是重要【英文标题】:Does order in which you wrap component with connect and withRouter matter使用 connect 和 withRouter 包装组件的顺序是否重要 【发布时间】:2018-08-29 06:29:45 【问题描述】:

哪个 HOC 将包装另一个。用多个 HOC 包装的顺序是否重要?我已经创建了多个 HOCs withSocketwithLoadingBar 等。我应该担心深度丑陋的嵌套,它会影响组件的性能吗?

【问题讨论】:

【参考方案1】:

多个 HOC 的包装顺序在 react 中是否重要?

包装 HOC 的顺序很重要,因为 props 从一个 HOC 传递到其子组件。考虑下面的例子

const mapStateToProps(state, props) 
   console.log(props.match);
   return 
      match: props.match
   

第一种情况:

withRouter(connect(mapStateToProps)(App));

在这种情况下,由于withRouter 包装了connectwithRouter ie history, match etc 提供的道具在连接使用的mapStateToProps 中可用。

想想像这样的 HOC

const MyComponent = connect(mapStateToProps)(App);
export default withRouter(MyComponent);

withRouter 可以像这样实现

const withRouter = (Comp) => 
    return class Something extends React.Component 
      render() 
         return <Comp match=this.context.router.match />
      
    
    ..

所以在这种情况下,CompMyComponentwithRouter 包裹接收匹配道具,在上述情况下是被 connect 包裹的组件

第二种情况:

connect(mapStateToProps)(withRouter(App));

在这种情况下,由于 connect 包装了 withRouter,withRouterhistory, match etc 提供的 props 如果不是由 connect 提供的 mapStateToProps父母。

我应该担心嵌套太深吗?

只有当一个 HOC 提供的 props 被另一个 HOC 使用时,你才应该担心它。假设你直接在基础组件中使用从 HOC 传递下来的 props,你就不需要担心顺序

会对组件的性能产生影响吗?

使用 HOC 的顺序不会影响组件的性能

查看以下代码框以获取示例

【讨论】:

我认为恰恰相反。您需要先应用withRouter,才能在mapStateToProps 中的ownProps 中拥有match 对象。嵌套函数从内部函数调用到外部函数。所以你的第一个案例是行不通的。 @trixn,是的,这就是我在回答中写的。不是很清楚吗?? 不,您在第一种情况下写道,match 将在 mapStateToProps 中可用,但由于您应用 withRouter() 之后 connect() 已经被调用。 @trixn,加了个demo解释一下 感谢@ShubhamKhatri 提供如此详细的解释【参考方案2】:

React 完全是关于组合的,在大多数情况下,它根本不应该是性能问题。在您真正意识到性能问题之前,请不要担心。嵌套 HOC 也很好。您唯一需要考虑的是,当一个 HOC 消耗另一个 HOC 注入的 props 时。这是例如当您需要mapStateToProps 中的react-router url 参数以通过id 选择对象时的情况。然后,您需要先应用 connect() HOC,然后再应用 withRouter() HOC 才能访问包装组件的 ownProps 中的 match 对象。

【讨论】:

以上是关于使用 connect 和 withRouter 包装组件的顺序是不是重要的主要内容,如果未能解决你的问题,请参考以下文章

输入一个同时使用 withRouter 和 connect 的 HOC 组件

为啥 withRouter 与 connect() 一起使用会破坏我的反应应用程序?

浅谈connect,withRouter,history,useState,useEffect

如何将 TypeScript 与 withRouter、connect、React.Component 和自定义属性一起使用?

[Redux] Using withRouter() to Inject the Params into Connected Components

带连接的 withRouter 在 v5.0.0 中不起作用?