高阶组件
2020-06-25 本文已影响0人
海豚先生的博客
- higher-order-component (高阶组件HOC)类似于高阶函数,它接受一个React组件作为参数,返回一个新的React组件。
- 通俗点讲就是:当React组件被包裹时(wrapped),高阶组件会返回一个加强的React组件。 高阶组件让我们的代码更具有复用性、逻辑性和抽象特征。它可以对render方法作劫持,也可以控制props和state
- 实现高阶组件有两种方式:
属性代理(props proxy)。高阶组件通过被包裹的React组件来操作props
反向继承(inheritance inversion)。 高阶组件继承于被包裹的React组件。
class InBox extends React.Component {
handleClick () {
console.log(this)
}
render() {
return (
<div>
<div>this.is {this.props.a}+{this.props.b}</div>
<div onClick={::this.handleClick} >点击</div>
</div>
)
}
}
function HOC(InboxInstance) {
return class box extends React.Component {
fn = (InboxInstance) => {
console.log(InboxInstance)
// 调用Inbox组件中的方法
InboxInstance.handleClick()
}
render() {
let props = {
...this.props,
a: 'aaa',
b: 'bbb'
}
props = Object.assign({},this.props,{ref:this.fn.bind(this)})
return (
// 控制props
<InBox {...props} />
)
}
}
}
export default HOC(InBox)
//->render 结果: this.is aaa+bbb
稍作修改官方的例子
// 父组件
import Hoc from "./Hoc"
class Fancy extends React.Component {
constructor(props) {
super(props)
this.ref = React.createRef()
}
handleClick = () => {
console.log(this.ref.current) // h2元素
this.setState({ // 触发更新函数
labbel: "点我",
})
}
render() {
return (
<Hoc label={this.state.label} handleClick={this.handleClick} ref={this.ref} />
)
}
}
// 子组件
function logProps(WrappedComponent) {
class LogProps extends React.Component {
componentDidUpdate(prevProps) {
console.log("old props:", prevProps)
console.log("new props:", this.props)
}
render() {
const { forwardedRef, ...rest } = this.props
return <WrappedComponent ref={forwardedRef} {...rest} />
}
}
return React.forwardRef((props, ref) => {
return <LogProps {...props} forwardedRef={ref} />
})
}
const FancyButton = React.forwardRef((props, ref) => {
const { handleClick, label } = props
return (
<div>
<h1>{"hello"}</h1>
<h2 ref={ref} onClick={handleClick}>
{label}
</h2>
</div>
)
})
export default logProps(FancyButton)