高阶组件(HOC)是react 中对组件逻辑进行重用的高级技术.但高阶组件本身并不是React API . 他只是一种模式,这种模式是由react自身的组件性质必然产生的.
具体而言,高阶组件就是一个函数,且该函数接受一个组件作为参数,并返回一个新的组件.
const enhancedComponent = higherOrderComponent ( WrappedComponent );
对比组件将 props 属性转变成UI, 高阶组件则是将一个组件转换成另一个新的组件.
高阶组件在 React 第三方库中很常见,比如 Redux 的 connect 方法和 Relay 的 creat
eContainer.
在React 中,组件是代码复用的主要单元. 然而你会发现,一些模式并不适用传统的组件.
我们写一个函数,该函数接收一个子组件作为其中的一个参数,并从数据源订阅数据作为 props 属性传入子组件.我们把这个函数取名字为: 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() {
//使用最新的数据渲染组件
//注意此处将已有的 props 属性传递给原组件
return <WrappedComponent data={this.state.data} {...this.props} />
}
}
}
和普通组件一样,withSubscription 和包裹组件之间的关联是完全基于props 属性的. 只要保证备选的集中高阶组件向包裹组件提供是相同类型的props 属性即可.
注意: 高阶组件既不会修改 input 原组件,也不会使用继承复制 input 原组件的行为. 相反,高阶组件是通过将原组件 包裹(wrapping) 在容器组件里面的方式来 组合(container component) 使用原组件. 高阶组件就是一个没有副作用的纯函数.
包裹组件接收容器组件的所有props 属性以及一个新的data属性,并用data 属性渲染输出内容.高阶组件并不关心数据是如何以及为什么被使用,而包裹组件也不关心数据来自何处.
三约定三注意:
约定一: 将不相关的props 属性传递给包裹组件.
约定二: 最大化使用组合
约定三: 包装显示名字以便于调试
注意一: 不要在render 函数中使用高阶组件
注意二: 必须将静态方法做拷贝
注意三: Refs 属性不能传递.