React 高阶组件
什么是高阶组件
高阶组件的定义:高阶组件是一个函数,它接受一个组件作为参数,返回一个新的组件,这就是高阶组件。 高阶组件把一个组件转化为另一个组件主要就是增强原来的组件,逻辑复用等。
高阶组件使用及编写结构
在介绍高阶组件怎么写之前先看一下怎么用,有下面两种方式:
- 作为函数调用
function App() {}
export default observer(App)
- 装饰器模式
@observer
class App extends React.Component {}
类的装饰器是ES6中新增的内容,装饰器的行为就是下面这样
@decorator
class A {}
// 等同于
class A {}
A = decorator(A) || A;
有的高阶组件还可以传参数
function App() {}
export default connect(mapPropsToState)(App)
有了上面的使用,我们基本上可以知道高阶组件的编写结构了
function observer(WrappedComponent) {
return class extends React.Component {
/** 编写逻辑 **/
render() {
<WrappedComponent {...this.props} />
}
}
}
或
function observer(WrappedComponent) {
return (props) => <WrappedComponent {...props} />
}
有些高阶组件需要参数,比如 react-redux 的 connect
connect(mapStateToProps)(Component)
对于这样的高阶组件我们需要再抽象一层
function connect (mapStateToProps){
return function wrapWithConnect(WrappedComponent) {
return function ConnectFunction(props){
}
}
}
高阶组件的实现
属性代理
给组件增加新的属性,比如,mobx-react 的 inject 组件
const inject = (...storeNames) => component => {
const Injector = React.forwardRef((props, ref) => {
const context = useContext(MobXProviderContext)
const newProps = {
...props,
...context // 给组件新增的属性
}
if (ref) {
newProps.ref = ref
}
return React.createElement(component, newProps)
})
return Injector
}
劫持渲染
比如 mobx-react 的 observer 就是劫持了组件的渲染,使其变为可自动更新的组件
observer 实现的思路如下, 我们简化流程,主要目的是说明高阶组件的编写
function observer(WrappedComponent) {
// 针对类组件
if (component.prototype && component.prototype.isReactComponent) {
return makeClassComponentObserver(WrappedComponent)
}
function makeClassComponentObserver(componentClass) {
const target = componentClass.prototype
const baseRender = target.render
// 劫持了原组件的render方法,使其变为响应式
target.render = function() {
return makeComponentReactive.call(this, baseRender) // makeComponentReactive 方式的实现省略...
}
return componentClass
}
}
总结
上面两种高阶组件的实现方式只是起到抛砖引玉的作用,高阶组件可以做很多事情,比如:复用逻辑、强化props、增强功能、赋能组件、控制渲染等。