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

Posted

技术标签:

【中文标题】使用多个 HOC 包装器导出 React 组件?【英文标题】:Exporting React component with multiple HOC wrappers? 【发布时间】:2018-07-12 04:25:46 【问题描述】:

我有一个显示样式文本的 React 组件,我想让它加载网络资源、侦听 WebSocket 输入并显示通知。为了做到这一点,我为其中的每一个编写了高阶组件包装函数:withResourcewithSocketwithNotifications

导出组件时,这样是否正确?

class TextComponent extends React.Component 
  ...


export default withResource(withSocket(withNotifications(TextComponent)))

【问题讨论】:

我可以知道你从哪里得到这个“withSocket”吗? 只是理论上的例子,所以不存在。我想它会包含用于通过套接字发送/响应通信的辅助方法,可能会插入像socket.io 这样的库。 【参考方案1】:

您可以从redux 或recompose 使用compose。例如:

还原

import  compose  from 'redux'

export default compose(
  withResource,
  withSocket,
  withNotifications
)(TextComponent)

重构

import  compose  from 'recompose'

export default compose(
  withResource,
  withSocket,
  withNotifications
)(TextComponent)

【讨论】:

优秀。我在这个项目中没有使用 redux,但是 lodash/fp 中也可以使用 compose。 pipe() 应该也可以,不是吗? @superhawk610 不客气。 recompose 也提供相同的实用程序。 为什么不使用嵌套方法 withResource(withSocket(withNotifications(TextComponent))) @Ehsansarshar 它也有效。这种方法的问题在于,很难推断出使用了哪些 HOC。特别是如果将来这些 HOC 中的任何一个更改其签名。做出改变会更难。想象一下,你有一个包含大量 HOC 的组件:withHOC1(withHOC2(withHOC3(withHOC4(withHOC5(withHOC6)))))... 我认为它的可读性不够。 这个解决方案对我帮助很大,通过这个例子我能够更好地理解 Redux 对 React 状态的优势【参考方案2】:

它被称为函数组合,它具有数学背景(导致 yx 变量命名和函数的反向执行)。它通过消除变量的额外定义和深层函数包装来降低调用书面函数的方式的复杂性。

自己编写或从库中使用,例如:lodashrambdaredux 等。

const compose = (...rest) => x => rest.reduceRight((y, f) => f(y), x)

第一类函数一起使用

const increment = (numb) => numb + 1
const multiplyBy = (multiplyNum) => (num) => multiplyNum * num

compose(increment, multiplyBy(3), increment)(4)// 4 > 5 > 15 > 16

高阶组件一起使用

compose(withRouter, withItems, withRefs)(Component) 

【讨论】:

【参考方案3】:

另一个简单的解决方案是分三步完成,只需像这样将 HOC 组件放在一起:

const firstHOC = withNotifications(TextComponent);
const secondHOC = withSocket(firstHOC);
export default withResource(secondHOC);

【讨论】:

以上是关于使用多个 HOC 包装器导出 React 组件?的主要内容,如果未能解决你的问题,请参考以下文章

React Redux 使用带有连接组件的 HOC

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

在 React 中定义和导出 HOC

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

React: 高阶组件(HOC)

在带有装饰器和 HOC 的类组件中使用 react-i18next