高阶组件(HOC),它描述的便是接受React组件作为输入,输出一个新的React组件的组件。更通俗地描述为,高阶组件通过包裹(wrapped)被传入的React组件,经过一系列处理,最终返回一个相对增强(enhanced)的React组件,供其他组件调用。它只是处理统一包装(处理)其它组件的一种模式。
const EnhancedComponent = higherOrderComponent(WrappedComponent);
高阶组件在React第三方库中很常见,比如Redux的connect方法和Relay的createContainer。下面是一个高阶组件的Demo,组件HocDemo经过包装后加上Token作为入参。
模拟获取Token:
// DataSource.js
export const TokenAction = {
getToken: function() {
// 通过计算获取一个有效token值
return "mytoken";
}
}
将要被包装的组件:
// HocDemo.jsx
import React from 'react';
class HocDemo extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return(
<div>{this.props.data},{this.props.token}</div>
);
}
}
export default HocDemo;
定义高阶组件处理函数WithToken:
import React from 'react';
import { TokenAction } from './DataSource.js';
var WithToken = function(WrappedComponent, autoData) {
// ……返回另一个新组件……
return class extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {
data: autoData,
token: TokenAction.getToken()
};
}
handleChange(newData) {
this.setState({
data: newData
});
}
render() {
// ……使用最新的数据渲染组件
// 注意此处将已有的props属性传递给原组件
return <WrappedComponent data={this.state.data} token={this.state.token} {...this.props} />;
}
};
}
export default WithToken;
渲染实现:
import React from 'react';
import WithToken from './components/hoc/WithToken.js'; //
import HocDemo from './components/hoc/HocDemo.jsx'; //
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
data: "高阶组件"
};
}
render() {
const HocDemoWithToken = WithToken(HocDemo, this.state.data);
return(
// 高阶组件
<HocDemoWithToken />
);
}
}
export default App;
<HocDemoWithToken>就是最终经过包装出来的高阶组件。高阶组件除了可以包装属性作为入参外,还可以包装标签、样式、事件监听,可以根据项目实际需要提供组件的某种增强模式。