reactjs - React 中高阶组件的用例?
问题描述
官方 react.js 上的教程component composition
描述了如何使用组合来避免继承,并且在大多数情况下我看到了这里的优势。
但该网站也提到了we haven’t found any use cases where we would recommend creating component inheritance hierarchies
src:https ://reactjs.org/docs/composition-vs-inheritance.html
但是我们有一个关于 HOC(高阶组件)模式
src 的教程:https
://reactjs.org/docs/higher-order-components.html
它建议编写用于生成复合组件的函数,以避免重复逻辑。
这种模式也用于 Relay 中用于使用 GraphQL 的组件。
对于来自 C#/Java/PHP 背景的人来说,他们的 HOC 用例看起来像是何时使用继承的明显示例。这是我之前在 React 中所做的,发现它非常直观,更重要的是易于调试。
我也在努力理解 HOC 中使用的生成器函数相对于常规复合组件的优势,后者通过道具获取内部组件。
所以我的问题是:React 中的 HOC 用例是否不能通过组合或继承来轻松解决?
示例将不胜感激。
更新:发现这篇文章Inheritance Inversion
建议让你的包装类从你的内部类继承并调用它的 render() 方法。
我可能有偏见,所以我不会马上放弃这个想法,因为它可能有实际用途,但我必须先更多地研究它。
如果您知道这何时可以击败常规组合或继承,请发表评论,或者如果您认为自己有一个很好的案例,请留下一个答案。
解决方案
对于那些来自任何面向对象语言(如Java )的人来说,重要的是要考虑到Javascript是一种基于原型的语言,这意味着可以通过具有克隆和扩展能力的通用对象来共享对象属性和方法。这称为原型继承,与类继承不同。在 Javascript 中,过多的继承会导致无尽的混乱,当你尝试调试这样的代码时会产生无尽的痛苦,也会影响性能,这就是为什么如果你阅读 Facebook 的文章
在 Facebook,我们在数以千计的组件中使用 React,我们还没有发现任何建议创建组件继承层次结构的用例
说到这里,我们不应该将HOC和Composition两种不同模式的概念混为一谈。它们有不同的用例。
高阶组件 (HOC)是 React 中用于重用组件逻辑的高级技术。通过阅读以下示例:
它似乎是一种模式,就像何时使用继承的明显示例一样,但事实并非如此。HOC 中涉及的逻辑不仅如此。
一些例子
- React-Redux 使用名为 connect的 HOC 将 存储状态映射到道具
- React-Router 的 withRouter HOC 为需要访问历史 API 的组件提供路由上下文
React 中的 HOC 用例是否不能通过组合或继承来轻松解决?
我会说始终避免继承,并根据您的需要选择组合或HOC,考虑到如果您选择组合,您至少必须尝试遵循以下常见规则:
- 将组件分为有状态的“组合”和无状态的“组件”。
- 如果两个组件需要访问相同的状态,请将状态移动到它们的共同父级。https://reactjs.org/docs/lifting-state-up.html
一个例子:
class Composed extends React.Component {
state = {
value: 'foo'
}
changeValue = value => this.setState({value})
render() {
<div>
<Component1 value={this.state.value} changeValue={this.changeValue} />
<Component2 value={this.state.value} />
<div>
}
}
希望有所帮助。
推荐阅读
- django - Django Heroku - ModuleNotFoundError:没有名为“django_social_share”的模块
- python - 如何防止在文本和形状之间绘制额外的线?
- macos - 如何在 Macintosh 代码中选择所有格代词
- mysql - 查询间并行性和查询内并行性有什么区别?
- xml - 谷歌表格中的 importxml 功能不适用于特定网站
- amazon-web-services - AWS SWF - 活动客户端生成不起作用(Maven、IntelliJ)
- azure - 将多个 Azure Functions 角色分配给 ARM 模板中的同一存储帐户
- angular - 角度测试:缺少区域设置“XXX”的区域设置数据
- node.js - 如何编写等待 next() 的异步快速中间件
- c++ - TensorFlow GPU 内存配置文件