😊文章略长,作好内心准备哦,建议阅读15分钟。html
在下面不少案例中用到了装饰器(@),这里提早说明下,修饰器(Decorator)是一个函数,用来修改类的行为。react
更多用法可参考简书一篇文章:www.jianshu.com/p/275bf41f4…es6
const EnhancedComponent = higherOrderComponent(WrappedComponent)bash
function hoc(WrappedComponent) {
return class HOC extends React.Component {
componentDidMount() {
console.log("hoc");
}
render() {
return <WrappedComponent />
}
}
}
// 使用高阶组件
class ComponentClass extends React.Component {
render() {
return <div></div>
}
}
export default hoc(ComponentClass);
// 做为装饰器使用
@hoc
export default class ComponentClass extends React.Component {
//...
}
复制代码
// 添加新的props
function ppHOC(WrappedComponent) {
return class PP extends React.Component {
render() {
const newProps = {
user: currentLoggedInUser
}
return <WrappedComponent {...this.props} {...newProps}/>
}
}
}
复制代码
// WrappedComponent初始渲染时候会调用ref回调,传入组件实例,在proc方法中,就能够调用组件方法
function refsHOC(WrappedComponent) {
return class RefsHOC extends React.Component {
proc(wrappedComponentInstance) {
wrappedComponentInstance.method()
}
render() {
// Object.asign();将全部可枚举属性的值从一个或多个源对象复制到目标对象
const props = Object.assign({}, this.props, {ref: this.proc.bind(this)})
return <WrappedComponent {...props}/>
}
}
}
复制代码
// 提取了 input 的 value 和 onChange 方法
function ppHOC(WrappedComponent) {
return class PP extends React.Component {
state = {
name: ''
}
onNameChange(event) {
this.setState({
name: event.target.value
})
}
render() {
const newProps = {
name: {
value: this.state.name,
onChange: this.onNameChange.bind(this)
}
}
return <WrappedComponent {...this.props} {...newProps}/>
}
}
}
// 使用方式以下
@ppHOC
class Example extends React.Component {
render() {
// 使用ppHOC装饰器以后,组件的props被添加了name属性,input会成为受控组件
return <input name="name" {...this.props.name}/>
}
}
复制代码
function ppHOC(WrappedComponent) {
return class PP extends React.Component {
render() {
return (
<div style={{display: 'block'}}>
<WrappedComponent {...this.props}/>
</div>
)
}
}
}
复制代码
// 过滤掉原组件中的ul元素
function hoc(ComponentClass) {
return class HOC extends ComponentClass {
render() {
const elementTree = super.render();
elementTree.props.children = elementTree.props.children.filter((z) => z.type !== "ul")
return React.cloneElement(elementTree);
}
}
}
@hoc
export default class ComponentClass extends React.Component {
render() {
return (
<div>
<p style={{color: 'brown'}}>啦啦啦</p>
<ul>
<li>1</li>
<li>2</li>
</ul>
</div>
)
}
}
复制代码
export function IIHOC(WrappedComponent) {
return class II extends WrappedComponent {
render() {
return (
<div>
<p>Props</p> <pre>{JSON.stringify(this.props, null, 2)}</pre>
<p>State</p><pre>{JSON.stringify(this.state, null, 2)}</pre>
{
super.render()
}
</div>
)
}
}
}
复制代码
// 假设this.props.loggedIn为真,HOC会彻底渲染WrappedComponent 的渲染结果
function iiHOC(WrappedComponent) {
return class ii extends WrappedComponent {
render() {
if (this.props.loggedIn) {
return super.render()
} else {
return null
}
}
}
}
复制代码
// 用HOC包裹的组件会丢失原先的名字,影响开发和调试,能够在WrappedComponent的名字加前缀来做为HOC的名字
const componentName = WrappedComponent.displayName || WrappedComponent.name || 'Component';
static displayName = `withModal(${componentName})`;
复制代码
//经过多重高阶组件肯定key并设定组件
const withStorage = (key) => WrappedComponent => {
return class extends Component {
componentWillMount() {
let data = localStorage.getItem(key);
this.setState({data});
}
render() {
return <WrappedComponent data={this.state.data} {...this.props} />
}
}
}
@withStorage('data')
class MyComponent2 extends Component {
render() {
return <div>{this.props.data}</div>
}
}
@withStorage('name')
class MyComponent3 extends Component {
render() {
return <div>{this.props.data}</div>
}
}
复制代码
const modalHoc = (options) => WrappedComponent => {
const componentName = WrappedComponent.displayName || WrappedComponent.name || 'Component';
return class ModalComponent extends Component {
static displayName = `withModal(${componentName})`;
render() {
const {visible, onCancel} = this.props;
let title;
if (typeof options === 'string') title = options;
if (typeof options === 'function') title = options;
if (typeof options === 'object') title = options.title;
if (typeof title === 'function') title = title(this.props);
return (
<Modal
destroyOnClose
width="60%"
bodyStyle={{padding: 0}}
footer={null}
{...options}
title={title}
onCancel={onCancel}
visible={visible}
>
<WrappedComponent {...this.props}/>
</Modal>
);
}
}
};
@modalHoc('能够传入不一样类型标题')
复制代码
😊 参考连接:react.html.cn/docs/higher…app
😊 刚刚加入掘金社区,欢迎提出宝贵建议,一块儿进步学习!函数