React高阶组件

#积累/react

实现方式

  1. 属性代理,传入子组件,返回包装组件
  2. 反向继承,传入子组件,返回继承子组件的包装组件

属性代理

基本用法

1
2
3
4
5
6
7
8
9
10
11
12
13
import React, {Component} from 'React';
const MyContainer = WrappedComponent =>
class extends Component {
render () {
return <WrappedComponent {...this.props} />;
}
};

@MyContainer
class MyComponent extends Component {
render () {}
}
export default MyComponent;

控制props

1
2
3
4
5
6
7
8
9
const MyContainer = WrappedComponent =>
class extends Component {
render () {
const newProps = {
text: newText,
};
return <WrappedComponent {...this.props} {...newProps} />;
}
};

通过refs使用引用

1
2
3
4
5
6
7
8
9
10
11
12
const MyContainer = WrappedComponent =>
class extends Component {
proc (wrappedComponentInstance) {
wrappedComponentInstance.method ();
}
render () {
const props = Object.assign ({}, this.props, {
ref: this.proc.bind (this),
});
return <WrappedComponent {...props} />;
}
};

抽象 state

高阶组件可以分离组件内部状态,将原组件抽象为展示型组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
const MyContainer = WrappedComponent =>
class extends Component {
constructor (props) {
super (props);
this.state = {
name: '',
};
this.onNameChange = this.onNameChange.bind (this);
}
onNameChange (event) {
this.setState ({
name: event.target.value,
});
}
render () {
const newProps = {
name: {
value: this.state.name,
onChange: this.onNameChange,
},
};
return <WrappedComponent {...this.props} {...newProps} />;
}
};

//将input的name属性,和改变属性的方法,抽象到高阶组件中
@MyContainer
class MyComponent extends Component {
render () {
return <input name="name" {...this.props.name} />;
}
}

使用其他元素包裹WrappedComponent

通过高阶段组件,给传入组件设置父元素样式,组合其他组件

1
2
3
4
5
6
7
8
9
10
const MyContainer = WrappedComponent =>
class extends Component {
render () {
return (
<div style={{display: 'block'}}>
<WrappedComponent {...this.props} />
</div>
);
}
};

组件参数

有时候调用高阶组件时需要传入一些参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import React, {Component} from 'React';
function HOCFactoryFactory (...params) {
// 可以做一些改变 params 的事
return function HOCFactory (WrappedComponent) {
return class HOC extends Component {
render () {
return <WrappedComponent {...this.props} />;
}
};
};
}

HOCFactoryFactory (params) (WrappedComponent); // 或者
@HOCFatoryFactory (params)
class WrappedComponent extends React.Component {}

反向继承

基础用法

传入组件,返回继承传入组件的组件,并使用super.render()来渲染新组件

1
2
3
4
5
6
const MyContainer = WrappedComponent =>
class extends WrappedComponent {
render () {
return super.render ();
}
};

渲染劫持

高阶组件可以控制 WrappedComponent 的渲染过程

1
2
3
4
5
6
7
8
9
10
11
//条件渲染
const MyContainer = WrappedComponent =>
class extends WrappedComponent {
render () {
if (this.props.loggedIn) {
return super.render ();
} else {
return null;
}
}
};

控制 state

不建议控制state,会使得WrappedComponent 组件内部状态一团糟 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const MyContainer = WrappedComponent =>
class extends WrappedComponent {
render () {
return (
<div>
<h2>HOC Debugger Component</h2>
<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>
);
}
};