React 高阶组件(HOC)
官方文档: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)相关推荐
- [react] 高阶组件(HOC)有哪些优点和缺点?
[react] 高阶组件(HOC)有哪些优点和缺点? HOC 优点 通过传递props去影响内层组件的状态,不直接改变内层组件的状态,降低了耦合度 缺点 组件多层嵌套, 增加复杂度与理解成本 ref隔 ...
- 「react进阶」一文吃透React高阶组件(HOC)
一 前言 React高阶组件(HOC),对于很多react开发者来说并不陌生,它是灵活使用react组件的一种技巧,高阶组件本身不是组件,它是一个参数为组件,返回值也是一个组件的函数.高阶作用用于强化 ...
- react 高阶组件hoc使用
react 高阶组件hoc使用 1. 为什么使用高阶组件 2. 具体使用 2.1原代码: 2.2 使用hoc封装后 1. 为什么使用高阶组件 高阶组件(HOC)是 React 中用于复用组件逻辑的一种 ...
- React 高阶组件HOC使用总结
HOC(高阶组件) /*HOC(高阶组件): 接收一个组件,返回包装后的组件(增强组件)- 不是React API- 是一种设计模式,类似于装饰器模式- ≈ Mixin && > ...
- react 高阶组件HOC实现组件复用
目录 一 使用步骤 二 显示鼠标坐标 三 鼠标随图片移动 四 设置displayName 五 传递props 高阶组件HOC: Higher-Order Component,是一个函数,接收要包装的组 ...
- React高阶组件(HOC)的写法归纳
react高阶组件的写法总结 什么是高阶组件 高阶组件要解决什么问题 高阶组件的写法 什么是高阶组件 何为高阶组件(HOC),根据官方文档的解释:"高阶组件是react中复用组件逻辑的一项高 ...
- React 高阶组件HOC详解
参考链接: https://juejin.cn/post/6844903815762673671 https://juejin.cn/post/6844904050236850184 前言 高阶组件与 ...
- 条件渲染之react高阶组件——HOC
定义:它接受任何输入(多数时候是一个组件)并返回一个组件作为输出.返回的组件是输入组件的增强版本,并且可以在 JSX 中使用.不是react api而是一种设计模式. 作用:强化组件,复用逻辑,提升渲 ...
- React 高阶组件HOC、设置displayName、高阶组件传递props
文章目录 1. 高阶组件 使用步骤 2. 高阶组件设置displayName 3.传递props 1. 高阶组件 目的:实现状态逻辑复用.实现功能增强.返回一个增强组件. 高阶组件(HOC,Highe ...
- React高阶组件(HOC)模型理论与实践
什么是HOC? HOC(全称Higher-order component)是一种React的进阶使用方法,主要还是为了便于组件的复用.HOC就是一个方法,获取一个组件,返回一个更高级的组件. 什么时候 ...
最新文章
- 巨大的需求之下 人工智能如何更快落地?
- AntDB上使用uuid
- AI视觉组仙人一步之模型调优
- Expected more than 1 value per channel when training, got input size torch.Size
- Grad-CAM (CNN可视化) Python示例
- odoo定时发送邮件
- Linux 列出文件列表命令ls
- Direct2D的使用
- 字符串类型str方法
- 基于Prometheus的.NET 4.x应用服务监控
- 使用ArcSDE SQL操作怎么获得新对象的objectid、GUID
- Springboot中使用websocket发送信息给指定用户和群发
- 栈的应用c语言计算器思路,请问,用c语言做一个计算器 包括+-*/()的运算 用栈 该怎么做...
- [转载] issubclass在python中的意思_python issubclass 和 isinstance函数
- 《转》SAP RM07扩展
- while 循环 格式化输出
- Linux下搭建打印机共享服务器(支持苹果AirPrint)
- 最好的在线PDF转换工具服务
- ARM树莓派高级开发——linux内核源码、树莓派源码编译、SD卡挂载
- go juju/ratelimit 简单使用
热门文章
- error TS1323: Dynamic import is only supported when '--module' flag is 'commonjs' or 'esNex t'.
- 如何写cover letter 翻译自How to write a cover letter
- word修改题注样式图x 为图x.x(wps可用
- 学生如何提高专业英文阅读能力 精选
- mt4 虚拟服务器 配置,mt4云服务器配置
- mt4挂虚拟服务器,mt4怎么挂云服务器
- 京东物流王梓晨:打造全栈团队,你要避开这些大坑
- 主成分分析、因子分析及其有关的数学基础
- 计算机领域的术语与缩写,计算机和生活常用缩写与术语
- Ios王者微信抢先服务器,王者荣耀:iOS微信用户抢先体验!国服出装铭文,点击一键查看!...