1. 什么是高阶组件
大约 2 分钟
高阶组件
1. 什么是高阶组件
高阶组件就是一个函数,传给它一个组件,它返回另一个新组件。
const NewComponent = heightOrderComponent(OldComponent)
NewComponent 会使用传给它的组件作为子组件。
简单例子:
import React, { Component } from 'react'
export default (WrappedComponent) => {
class NewComponent extends Component {
//...
render () {
return <WrappedComponent />
}
}
return NewComponent
}
在高阶组件中添加一些数据启动工作:
import React, { Component } from 'react'
export default (WrappedComponent, name) => {
class NewComponent extends Component {
constructor () {
super()
this.state = { data: null }
}
componentWillMount () {
let data = localStorage.getItem(name)
this.setState({ data })
}
render () {
return <WrappedComponent data={this.state.data} />
}
}
return NewComponent
}
NewComponent 根据第二个参数name从LocalStorage中加载数据,并在渲染的时候将 state.data 通过 props.data 传给 WrappedComponent。
2. 高阶组件怎么用
假设上面的高阶组件存放在 src/wrapWithLoadData.js 文件中
1. 使用第一次
import wrapWithLoadData from './wrapWithLoadData'
class InputWithUserName extends Component {
render () {
return <input value={this.props.data} />
}
}
InputWithUserName = wrapWithLoadData(InputWithUserName, 'username')
export default InputWithUserName
可以看出如果想要从LocalStorage里加载 username 字段值作为 <input />
的值,通过wrapWIthLoadData可以轻易做到。
别人使用这个组件的时候实际是用了被加工过的组件
最终使用
import InputWithUserName from './InputWithUserName'
class Index extends Component {
render () {
return (
<div>
用户名:<InputWithUserName />
</div>
)
}
}
2. 使用第二次
再看看下面这个例子,我们又需要一个文本输入框,它需要从LocalStorage加载 content字段的数据。我们只需定义一个新的 TextareaWithContent.
import wrapWithLoadData from './wrapWithLoadData'
class TextareaWithContent extends Component {
render () {
return <textarea value={this.props.data} />
}
}
TextareaWithContent = wrapWithLoadData(TextareaWithContent, 'content')
export default TextareaWithContent
这里我们不需要重复写从LocalStorage加载数据字段的逻辑,直接使用高阶组件包装就可以使用。
3. 高阶组件作用
为了组件之间代码复用。
组件中相同的逻辑抽离出来放到高阶组件中进行复用
高阶组件内部的包装组件和被包装组件之间通过props传递数据