使用 HOC 与使用组件包装之间的区别

Posted

技术标签:

【中文标题】使用 HOC 与使用组件包装之间的区别【英文标题】:Difference between using a HOC vs. Component Wrapping 【发布时间】:2016-08-25 22:24:10 【问题描述】:

我刚刚检查了 React 中的 HOC。他们很酷。然而,简单地包装一个组件不也能达到同样的效果吗?

高阶组件

这个简单的 HOC 将状态作为属性传递给 ComposedComponent

const HOC = ComposedComponent => class extends React.Component 

    ... lifecycle, state, etc;...

    render() 
      return (<ComposedComponent ...this.state />);
          


组件包装

该组件将状态作为属性传递给子组件

class ParentComponent extends React.Component 

    ... lifecycle, state, etc;...

    render() 
      return (
        <div>
          React.cloneElement(this.props.children,  ...this.state )  
        </div>
      );
          


虽然两者的使用方式略有不同,但它们似乎都可以重复使用。

HOC 和通过 this.props.children 组合组件之间的真正区别在哪里?有没有只能使用其中一种的例子?使用 HOC 是一种更好的做法。这些只是您可以选择自己喜欢的口味的选择吗?

【问题讨论】:

“组件包装”是否与“容器组件”相同? 【参考方案1】:

高阶组件 (HOC) 和容器组件是不同的。它们有不同的用例,解决类似但不同的问题。

HOC 就像 mixins。它们用于组合被装饰组件知道的功能。这与包装子组件并允许子组件愚蠢(或了解容器的装饰功能)的容器组件相反。

确实,在传输 props 时,Container 可以为其子代添加功能。但是,这通常是以道具的形式传给孩子们的。在 Containers 中,这也很尴尬,因为您不能简单地将 props 添加到已创建的元素中:

因此,如果您想从this.props.children 为孩子添加新道具,则必须使用cloneElement。这效率不高,因为这意味着您必须重新创建元素。

此外,HOC 只是一种创建组件的方式(工厂)。所以,这可能发生在render之外。

【讨论】:

你能解释一下为什么“这也很尴尬,因为你不能简单地将道具添加到已经创建的元素中”? 我认为 Davin 的意思是 HOC 是通过组件实例调用的,HOC 可以在组件渲染之前向其中注入 props。容器组件的调用结果是渲染组件实例,而不是组件实例本身。 所以在同一个项目中同时看到这两种技术的情况并不少见?包含其“哑”子组件逻辑的容器,以及任何实现 HOC 以添加类似但非特定于域的功能的组件? 这是一个很好的答案,我认为应该强调“装饰组件知道”部分,因为这对我区分两者至关重要。跨度> 你说被装饰的组件知道 HOC 的功能是什么意思?我无法理解这一点。【参考方案2】:

我只是想补充一点,当您需要动态高阶组件时,Container 方法效果更好。

如果您有 4 个元素要渲染,并且可以定义一个 HOC,您希望在 render 内创建高阶组件,但由于在渲染内调用高阶组件会导致 &lt;HigherOrderComponent/&gt; 重新安装每次渲染都会变成一个非常糟糕的主意。

这在此处记录; https://github.com/facebook/react/blob/044015760883d03f060301a15beef17909abbf71/docs/docs/higher-order-components.md#dont-use-hocs-inside-the-render-method.

但总的来说,我会选择 HOC 方法。

【讨论】:

以上是关于使用 HOC 与使用组件包装之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

之间的区别是什么高阶组件(HOC)和继承反应本地组件

使用多个 HOC 包装器导出 React 组件?

使用 HOC 包装时,组件不会从 getStaticProps 接收道具

React: 高阶组件(HOC)

通过 HOC 将 React 上下文传递给包装的组件

如何用 HOC 包装每个导出的组件?