官方文档:https://zh-hans.reactjs.org/docs/higher-order-components.html

组件是 React 中代码复用的基本单元。但有时会发现某些模式并不合适传统组件。

含义

HOC 是灵活使用 react 组件的一个技巧,本身不是一个组件,是一个参数为组件,返回值是一个组件的函数。
HOC 本身不是 react 中 API 的一部分,是 react 的组合特性而形成的设计模式。

作用

* 强化组件

高阶组件返回的组件,可以劫持上一层传过来的 props,然后混入新的 props,来增强组件的功能。

1.混入 props

通过承接上层的 props,在混入自己的 props,来强化组件

function classHOC(WrapComponent){return class  Idex extends React.Component{state={name:'gs'}componentDidMount(){console.log('HOC')}render(){return <WrapComponent{ ...this.props }{...this.state }/>}}
}
function Index(props){const { name,...otherProps } = propsuseEffect(()=>{console.log( 'index' )},[])return <div>my name is { name }</div>
}export default classHOC(Index)

hooks 版本应用

function functionHoc(WrapComponent){return function Index(props){const [ state , setState ] = useState({ name :'gs'  })return  <WrapComponent { ...props }  { ...state }   />}
}

2.state 控制更新

可以将 HOC 的 state 的配合起来,控制业务组件的更新。类似用于处理来自 react-redux 中 state 更改,带来的订阅更新的作用。

function classHOC(WrapComponent){return class  Idex extends React.Component{constructor(){super()this.state={name:'gs'}}const changeName=(name)=>{this.setState({ name })}render(){return<WrapComponent{ ...this.props }{ ...this.state }changeName={this.changeName}/>}}
}
function Index(props){const [ value ,setValue ] = useState(null)const { name ,changeName } = propsreturn <div><div>   hello,world , my name is { name }</div>改变name <input onChange={ (e)=> setValue(e.target.value)  }  /><button onClick={ ()=>  changeName(value) }  >确定</button></div>
}export default classHOC(Index)

* 复用逻辑

高阶组件可以对 react 组件进行加工处理。可以根据需求对原有的组件进行加工,可以定制专属的 HOC。
官网例子:
例如,假设有一个 CommentList 组件,它订阅外部数据源,用以渲染评论列表:

class CommentList extends React.Component {constructor(props) {super(props);this.handleChange = this.handleChange.bind(this);this.state = {// 假设 "DataSource" 是个全局范围内的数据源变量comments: DataSource.getComments()};}componentDidMount() {// 订阅更改DataSource.addChangeListener(this.handleChange);}componentWillUnmount() {// 清除订阅DataSource.removeChangeListener(this.handleChange);}handleChange() {// 当数据源更新时,更新组件状态this.setState({comments: DataSource.getComments()});}render() {return (<div>{this.state.comments.map((comment) => (<Comment comment={comment} key={comment.id} />))}</div>);}
}

编写了一个用于订阅单个博客帖子的组件,该帖子遵循类似的模式:

class BlogPost extends React.Component {constructor(props) {super(props);this.handleChange = this.handleChange.bind(this);this.state = {blogPost: DataSource.getBlogPost(props.id)};}componentDidMount() {DataSource.addChangeListener(this.handleChange);}componentWillUnmount() {DataSource.removeChangeListener(this.handleChange);}handleChange() {this.setState({blogPost: DataSource.getBlogPost(this.props.id)});}render() {return <TextBlock text={this.state.blogPost} />;}
}

CommentList 和 BlogPost 不同 - 它们在 DataSource 上调用不同的方法,且渲染不同的结果。但它们的大部分实现都是一样的: 1.在挂载时,向 DataSource 添加一个更改侦听器。 2.在侦听器内部,当数据源发生变化时,调用 setState。 3.在卸载时,删除侦听器。
所以调用函数 withSubscription 函数进行处理:

const CommentListWithSubscription = withSubscription(CommentList,(DataSource) => DataSource.getComments()
);const BlogPostWithSubscription = withSubscription(BlogPost,(DataSource, props) => DataSource.getBlogPost(props.id)
);

withSubscription 函数逻辑处理:

// 此函数接收一个组件...
function withSubscription(WrappedComponent, selectData) {// ...并返回另一个组件...return class extends React.Component {constructor(props) {super(props);this.handleChange = this.handleChange.bind(this);this.state = {data: selectData(DataSource, props)};}componentDidMount() {// ...负责订阅相关的操作...DataSource.addChangeListener(this.handleChange);}componentWillUnmount() {DataSource.removeChangeListener(this.handleChange);}handleChange() {this.setState({data: selectData(DataSource, this.props)});}render() {// ... 并使用新数据渲染被包装的组件!// 请注意,我们可能还会传递其他属性return <WrappedComponentdata={this.state.data}{...this.props}/>;}};
}

* 事件监控

HOC 还可以对原有组件进行监控。比如对一些事件监控,错误监控,事件监听等一系列操作。


function ClickHoc (Component){return  function Wrap(props){const dom = useRef(null)useEffect(()=>{const handleClick = () => console.log('发生点击事件')dom.current.addEventListener('click',handleClick)return () => dom.current.removeEventListener('click',handleClick)},[])return  <div ref={dom}  ><Component  {...props} /></div>}
}@ClickHoc
class Index extends React.Component{render(){return <div  className='index'  ><button>组件内部点击</button></div>}
}
export default ()=>{return <div className='box'  ><Index /><button>组件外部点击</button></div>
}

以上

React 高阶组件(HOC)相关推荐

  1. [react] 高阶组件(HOC)有哪些优点和缺点?

    [react] 高阶组件(HOC)有哪些优点和缺点? HOC 优点 通过传递props去影响内层组件的状态,不直接改变内层组件的状态,降低了耦合度 缺点 组件多层嵌套, 增加复杂度与理解成本 ref隔 ...

  2. 「react进阶」一文吃透React高阶组件(HOC)

    一 前言 React高阶组件(HOC),对于很多react开发者来说并不陌生,它是灵活使用react组件的一种技巧,高阶组件本身不是组件,它是一个参数为组件,返回值也是一个组件的函数.高阶作用用于强化 ...

  3. react 高阶组件hoc使用

    react 高阶组件hoc使用 1. 为什么使用高阶组件 2. 具体使用 2.1原代码: 2.2 使用hoc封装后 1. 为什么使用高阶组件 高阶组件(HOC)是 React 中用于复用组件逻辑的一种 ...

  4. React 高阶组件HOC使用总结

    HOC(高阶组件) /*HOC(高阶组件): 接收一个组件,返回包装后的组件(增强组件)- 不是React API- 是一种设计模式,类似于装饰器模式- ≈ Mixin && > ...

  5. react 高阶组件HOC实现组件复用

    目录 一 使用步骤 二 显示鼠标坐标 三 鼠标随图片移动 四 设置displayName 五 传递props 高阶组件HOC: Higher-Order Component,是一个函数,接收要包装的组 ...

  6. React高阶组件(HOC)的写法归纳

    react高阶组件的写法总结 什么是高阶组件 高阶组件要解决什么问题 高阶组件的写法 什么是高阶组件 何为高阶组件(HOC),根据官方文档的解释:"高阶组件是react中复用组件逻辑的一项高 ...

  7. React 高阶组件HOC详解

    参考链接: https://juejin.cn/post/6844903815762673671 https://juejin.cn/post/6844904050236850184 前言 高阶组件与 ...

  8. 条件渲染之react高阶组件——HOC

    定义:它接受任何输入(多数时候是一个组件)并返回一个组件作为输出.返回的组件是输入组件的增强版本,并且可以在 JSX 中使用.不是react api而是一种设计模式. 作用:强化组件,复用逻辑,提升渲 ...

  9. React 高阶组件HOC、设置displayName、高阶组件传递props

    文章目录 1. 高阶组件 使用步骤 2. 高阶组件设置displayName 3.传递props 1. 高阶组件 目的:实现状态逻辑复用.实现功能增强.返回一个增强组件. 高阶组件(HOC,Highe ...

  10. React高阶组件(HOC)模型理论与实践

    什么是HOC? HOC(全称Higher-order component)是一种React的进阶使用方法,主要还是为了便于组件的复用.HOC就是一个方法,获取一个组件,返回一个更高级的组件. 什么时候 ...

最新文章

  1. 巨大的需求之下 人工智能如何更快落地?
  2. AntDB上使用uuid
  3. AI视觉组仙人一步之模型调优
  4. Expected more than 1 value per channel when training, got input size torch.Size
  5. Grad-CAM (CNN可视化) Python示例
  6. odoo定时发送邮件
  7. Linux 列出文件列表命令ls
  8. Direct2D的使用
  9. 字符串类型str方法
  10. 基于Prometheus的.NET 4.x应用服务监控
  11. 使用ArcSDE SQL操作怎么获得新对象的objectid、GUID
  12. Springboot中使用websocket发送信息给指定用户和群发
  13. 栈的应用c语言计算器思路,请问,用c语言做一个计算器 包括+-*/()的运算 用栈 该怎么做...
  14. [转载] issubclass在python中的意思_python issubclass 和 isinstance函数
  15. 《转》SAP RM07扩展
  16. while 循环 格式化输出
  17. Linux下搭建打印机共享服务器(支持苹果AirPrint)
  18. 最好的在线PDF转换工具服务
  19. ARM树莓派高级开发——linux内核源码、树莓派源码编译、SD卡挂载
  20. go juju/ratelimit 简单使用

热门文章

  1. error TS1323: Dynamic import is only supported when '--module' flag is 'commonjs' or 'esNex t'.
  2. 如何写cover letter 翻译自How to write a cover letter
  3. word修改题注样式图x 为图x.x(wps可用
  4. 学生如何提高专业英文阅读能力 精选
  5. mt4 虚拟服务器 配置,mt4云服务器配置
  6. mt4挂虚拟服务器,mt4怎么挂云服务器
  7. 京东物流王梓晨:打造全栈团队,你要避开这些大坑
  8. 主成分分析、因子分析及其有关的数学基础
  9. 计算机领域的术语与缩写,计算机和生活常用缩写与术语
  10. Ios王者微信抢先服务器,王者荣耀:iOS微信用户抢先体验!国服出装铭文,点击一键查看!...