1、高阶组件是什么
高阶组件是一个函数,但 参数 和 返回值 为 组件。 高阶组件是包装了另外一个 React 组件的 React 组件、它可以大幅度的简化代码量、使我们更多的去复用代码; 高阶组件可以解决组件冗余的问题,可以使多个组件具有相同或类似的方法。
2、高阶组件用途
1): 最常用之属性代理:
/* eslint-disable*/
import React, { createRef, Component } from 'react';
const firstHoc = (WrappedComponent) => {
return class extends Component {
get hocComponent() {
return this.hocRef.current;
}
constructor(props) {
super(props);
this.state = {
userId: '',
};
this.logState = this.logState.bind(this);
this.hocRef = createRef();
}
componentWillMount() {
const userId = localStorage.getItem('userId');
this.setState({
userId,
});
}
logState() {
console.log('==============>', this);
console.log('====>', this.hocComponent.state);
}
render() {
const { userId } = this.state;
const hocProps = {
logState: this.logState,
userId,
};
return <WrappedComponent ref={this.hocRef} {...this.props} {...hocProps} />;
}
};
};
class Test extends Component {
constructor() {
super();
this.state = {
hocTest: '我是hocTest',
};
}
handleView = () => {
console.log(this.props.userId);
this.props.logState();
};
render() {
return (
<div
onClick={() => {
this.handleView();
}}
>
Test
</div>
);
}
}
export default firstHoc(Test);
以上例子是导出了 hoc 组件中的 logState 通过 firstHoc 包裹的组件、都可以直接调用 this.props.logState 去打印自身组件的 state 数据
即抽取一些可复用的方法,或属性导出,在子组件内通过 this.porps 访问
2): 抽离 state:
/* eslint-disable max-classes-per-file */
// 普通组件Login
import React, { Component } from 'react';
const formCreate = (WrappedComponent) =>
class extends Component {
constructor() {
super();
this.state = {
fields: {},
};
}
changeFiled = (e, key) => {
const { fields } = this.state;
fields[key] = e.target.value;
this.setState({
fields,
});
};
handleSubmit = () => {
console.log(this.state.fields);
};
render() {
const props = {
...this.props,
handleSubmit: this.handleSubmit,
changeFiled: this.changeFiled,
};
return <WrappedComponent {...props} />;
}
};
class Login extends Component {
render() {
return (
<div>
<div>
<label id="username">账户</label>
<input onChange={(e) => this.props.changeFiled(e, 'username')} />
</div>
<div>
<label id="password">密码</label>
<input onChange={(e) => this.props.changeFiled(e, 'password')} />
</div>
<div onClick={this.props.handleSubmit}>提交</div>
<div>other content</div>
</div>
);
}
}
export default formCreate(Login);
把子组件中重复功能(如一些简单的受控表单、使用 state 控制输入 value)的状态、及设置 state 抽离在高阶组件中统一管理! 最后在子组件中通过 this.porps.methodsName 获取
3): 统一容器:
const HocTest = (WrappedComponent) =>
class extends Component {
render() {
return (
<div style={{ background: '#fff' }}>
头部
<WrappedComponent {...props} />
尾部
</div>
);
}
};
可以在高阶组件中套一层 div 做一些公用样式… 其实还有很多作用
4): 反向继承(渲染劫持):
const withLoading(WrappedComponent) {
return class extends WrappedComponent {
render() {
if(this.props.isLoading) {
return <Loading />;
} else {
return super.render();
}
}
};
}
在 hoc 中直接继承传进来的组件(wrapComponent),在 render 中做一些判断,如是否处于 loading 状态,渲染 loading 或者直接渲染原来内容 super.render();
其实在工作中我们能遇到的使用高阶组件情景很多,就看我们怎么使用;
版权声明:本文为xuewenjie0217原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。