一.高阶组件
在工作过程中,会遇到很多重复性的功能,可能会有很多组件都会用到,为了减少重复代码,这个时候React 高阶组件HOC(Higher Order Component)就派上了用场。HOC接收一个组件而返回一个经过处理的新的组件。
HOC不是React API的一部分,它是一种基于React的组合特性而形成的设计模式。
现在我们来谈一谈HOC如何使用:
HOC分为两种方式,分别是代理方式和继承方式
1.代理方式
我们先来写一个简单的组件,代码如下:
import React, { Component } from 'react'
export default class BaseComponent extends Component{
render(){
const { user, title, content } = this.props;
return (
<div style={{...props}}>
<p>{user}</p>
<p>{title}</p>
<p>{content}</p>
</div>
);
}
}
HOC组件removeUserPropHOC.jsx:
import React, { Component } from 'react';
export default removeUserProp(WrappedComponent) {
return class NewComponent extends Component {
render() {
const {user, ...otherProps} = this.props;
const styles = { color: 'pink', backgroundColor: 'green' }
return(
<WrappedComponent {...otherProps} {...styles} />
);
}
}
}
index.jsx应用HOC组件:
import React, { Component } from 'react'
import BaseComponent from '../components/baseComponent'
import removeUserProp from '../HOCComponents/removeUserPropHOC'
export default class Index extends Component {
render() {
const styles = { color: 'pink', backgroundColor: 'green' }
const NewComponent = removeUserProp(BaseComponent, styles);
return (
<div>
<BaseComponent user='小红' title='标题' content='内容' />
<hr />
<NewComponent user='小红' title='标题' content='内容' />
<hr />
</div>
)
}
}
这样就可以看到user这个prop被成功过滤掉了,并且字体颜色变成了粉色,背景颜色变成了绿色, 这种传style给HOC的方式也叫做包装组件
上文removeUserProp高阶组件我们用的是extends继承方法来写的,如果没有用到状态(state)、生命周期或者其他复杂的逻辑,我们可以简写成以下形式:
import React, { Component } from 'react';
export default removeUserProp(WrappedComponent, styles) {
return function(props) {
const {user, ...otherProps} = props;
return(
<div style={style}>
<WrappedComponent {...otherProps} />
</div>
);
}
}
2.继承方式
用继承方式来写高阶组件主要是应用于操纵props以及生命周期
举个简单的例子:
export default function extendsComponent(WrappedComponent) {
return class NewComponent extends WrappedComponent {
shouldComponentUpdate() {
// 逻辑代码
}
render() {
const { user, ...otherProps } = this.props;
this.props = otherProps;
return super.render();
}
}
}
由于是直接继承自传入的组件,所以传入的组件必须是class组件而非函数式组件。return 也从返回组件变成了super.render()
当然,直接修改props是不安全的,而且继承式HOC操作麻烦,结构不够清晰,所以并不经常被使用,我们一般都是使用代理方式的高阶组件。
二.以函数为子组件
高阶组件并不是唯一提高React代码重用的方法。由于高阶组件扩展现有组件的功能的方式主要通过props的增减或者修改原有props。但是高阶组件的缺点是对原有组件的props产生了固化。这时,我们就可以用以函数为子组件这种更为灵活的方式。
在这种模式下,实现代码重用的不是一个函数,而是一个真正的React组件。只不过它必须有子组件存在,而且子组件必须是个函数。在组件示例的生命周期中this.props.children引用的就是子组件,得到的结果就是render返回的一部分。
举个例子:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
export default AddUser extends Component {
render() {
const user = loggedinuser;
return this.props.children(user)
}
}
AddUser.propTypes = {
children: PropTypes.func.isRequired
}
propTypes是react提供的类型检查工具,可以通过npm下载
npm install --save prop-types
使用:
<AddUserProp>
{(user) => (<div>{user}</div>)}
</AddUserProp>
这就是这两天学习React高阶组件的心得体会啦,欢迎补充留言哦~