代理方式的高阶组件
返回的新组件直接继承于React.Component类,新组件作为传入组件的一个代理,在新组件中渲染出被包裹组件。除了高阶组件自己要做的事情以外,其余全部由被包裹组件来做。
其有四种操作:
- 操纵props。
- 访问ref。
- 抽取状态。
- 包装组件。
1.操纵props:
我们拿组件B来做演示,给B加一个属性name。
import React from 'react';
import B from './components/B'
import C from './components/C'
import './App.css';
class App extends React.Component {
render() {
return (
<div>
<B name='李雷' />
<C />
</div>
);
}
}
在B组件中把name通过props显示出来,但是发现上面并未对sex属性赋值,我们可以在高阶组件中进行传入。
import React, { Component } from 'react'
import A from './A'
@A
class B extends Component {
render() {
console.log(this.props)
return (
<div>
<div>这是组件B</div>
<div>我的名字:{ this.props.name }</div>
<div>我的性别:{ this.props.sex }</div>
</div>
)
}
}
export default B
首先把根节点的props透传入组件B中,在添加一个新的属性sex。
import React, { Component } from 'react'
export default function A(WrappedComponent) {
return class A extends Component {
render() {
return (
<div className="box">
<div>我是公共组件A的内容</div>
<WrappedComponent {...this.props} sex={'男'} />
</div>
)
}
}
}
最终达到我们操作props的要求:
2.访问ref:
通过ref访问调用C的实例
import React, { Component } from 'react'
export default function A(WrappedComponent) {
return class A extends Component {
refContent(instance) {
instance.putOutComponent && console.log(instance.putOutComponent())
}
render() {
return (
<div className="box">
<div>我是公共组件A的内容</div>
<WrappedComponent { ...this.props } sex={ '男' } ref={ this.refContent } />
</div>
)
}
}
}
在C中加入putOutComponent方法
import React, { Component } from 'react'
import A from './A'
class C extends Component {
putOutComponent() {
return '这是组件C'
}
render() {
console.log(this.props)
return (
<div>这是组件C</div>
)
}
}
export default A(C)
控制台中显示组件C中内容方法,这样可以控制所有被包裹组件,以便与业务扩展。
3.抽取状态:
把input的value值和onInputChange方法从高阶组件中以props方式传入。
import React, { Component } from 'react'
import A from './A'
@A
class B extends Component {
render() {
return (
<div>
<input type='text' {...this.props} />
<br />
<div>这是组件B</div>
<div>我的名字:{ this.props.name }</div>
<div>我的性别:{ this.props.sex }</div>
</div>
)
}
}
export default B
设置newProps把value值和onInputChange传入,当输入内容改变时便会触发高阶组件onInputChange方法从而获取改变值的内容,同样可以在C组件中加入input在A高阶组件中进行控制。
import React, { Component } from 'react'
export default function A(WrappedComponent) {
return class A extends Component {
constructor(props) {
super(props)
this.state = {
value: ''
}
}
refContent(instance) {
instance.putOutComponent && console.log(instance.putOutComponent())
}
onInputChange = (e) => {
console.log(e.target.value)
this.setState({
value: e.target.value
})
}
render() {
const newProps = {
value: this.state.value,
onInput: this.onInputChange
}
return (
<div className="box">
<div>我是公共组件A的内容</div>
<WrappedComponent { ...this.props } sex={ '男' } ref={ this.refContent } {...newProps} />
</div>
)
}
}
}
4.包装组件:
包装组件指我们可以在高阶组件中设置公共部分,
我是公共组件A的内容
这里就是对组件的包装。return (
<div className="box">
<div>我是公共组件A的内容</div>
<WrappedComponent { ...this.props } sex={ '男' } ref={ this.refContent } {...newProps} />
</div>
)
以上就是代理方式的高阶组件介绍。