什么是高阶组件?
一个高阶组件只是一个包装了另外一个 React 组件的 React 组件。
高阶组件可以做什么?
- 代码复用,逻辑抽象,抽离底层准备(bootstrap)代码
- 渲染劫持
- State 抽象和更改
- Props 更改
如何实现高阶组件
- 1.属性代理
- 2.反向继承
属性代理
function HOC(WrappedComponent){
return class HOC extends Component {
render(){
const newProps = {type:'HOC'};
return <div>
<WrappedComponent {...this.props} {...newProps}/>
</div>
}
}
}
@HOC
class OriginComponent extends Component {
render(){
return <div>这是原始组件</div>
}
}
//const newComponent = HOC(OriginComponent)
Props Proxy 可以做什么?
- 更改 props
- 通过 refs 获取组件实例
- 抽象 state
- 把 WrappedComponent 与其它 elements 包装在一起
上面的例子是使用属性代理的方法,增加了一个props属性
反向继承
function HOC(WrappedComponent){
return class HOC extends WrappedComponent {
//继承了传入的组件
test1(){
return this.test2() + 5;
}
componentDidMount(){
console.log('1');
this.setState({number:2});
}
render(){
//使用super调用传入组件的render方法
return super.render();
}
}
}
@HOC
class OriginComponent extends Component {
constructor(props){
super(props);
this.state = {number:1}
}
test2(){
return 4;
}
componentDidMount(){
console.log('2');
}
render(){
return (
<div>
{this.state.number}{'and'}
{this.test1()}
这是原始组件
</div>
)
}
}
//const newComponent = HOC(OriginComponent)
上述例子使用了方向代理,为何叫反向继承呢,因为OriginComponent是被动的被HOC继承,反向继承可以做劫持渲染
可以用反向继承高阶组件做什么?
- 渲染劫持(Render Highjacking)
- 操作 state
你无法更改或创建 props 给 WrappedComponent 实例,因为 React 不允许变更一个组件收到的 props,但是你可以在 render 方法里更改子元素/子组件们的 props。
例子1:条件性渲染。如果 this.props.loggedIn 是 true,这个高阶组件会原封不动地渲染 WrappedComponent,如果不是 true 则不渲染(假设此组件会收到 loggedIn 的 prop)
function iiHOC(WrappedComponent) {
return class Enhancer extends WrappedComponent {
render() {
if (this.props.loggedIn) {
return super.render()
} else {
return null
}
}
}
}
参考