什么是高阶组件?
高阶部件是一种用于复用组件逻辑的高级技术,它并不是 React API的一部分,而是从React 演化而来的一种模式。 具体地说,高阶组件就是一个接收一个组件并返回另外一个新组件的函数!
解决什么问题?
随着项目越来越复杂,开发过程中,多个组件需要某个功能,而且这个功能和页面并没有关系,所以也不能简单的抽取成一个新的组件,但是如果让同样的逻辑在各个组件里各自实现,无疑会导致重复的代码。比如页面有三种弹窗一个有title,一个没有,一个又有右上角关闭按钮,除此之外别无它样,你总不能整好几个弹窗组件吧,这里除了tilte,关闭按钮其他的就可以做为上面说的基本材料。
高阶组件总共分为两大类
-
代理方式
-
操纵prop
-
访问ref(不推荐)
-
抽取状态
-
包装组件
-
继承方式
-
操纵生命周期
-
操纵prop
代理方式之 操纵prop
import React from 'react'function HocRemoveProp (WrappedComponent) { return class WrappingComPonent extends React.Component{ render() { const { user, ...otherProps } = this.props; return} }}export default HocRemoveProp;
增加prop
接下来我把简化了写法,把匿名函数去掉,同时换成箭头函数
import React from 'react'const HocAddProp = (WrappedComponent,uid) => class extends React.Component { render() { const newProps = { uid, }; return} }export default HocAddProp;
两个高阶组件的使用方法:
-
const newComponent = HocRemoveProp(SampleComponent);
-
const newComponent = HocAddProp(SampleComponent,'1111111');
也可以利用decorator语法糖这样使用
import React, { Component } from 'React';@HocRemovePropclass SampleComponent extends Component { render() {}}export default SampleComponent;
代理方式之 抽取状态
将所有的状态的管理交给外面的容器组件,这个模式就是 抽取状态 外面的容器就是这个高阶组件
const HocContainer = (WrappedComponent) => class extends React.Component{ constructor(props) { super(props) this.state = { name: '' } } onNameChange = (event) => { this.setState({ name: event.target.value }) } render() { const newProps = { name: { value: this.state.name, onChange: this.onNameChange } } return} }
@HocContainerclass SampleComponent extends React.Component { render() { return }}
这样当我们在使用这个已经被包裹的input组件(SampleComponent)时候 它的值就被放在了HocContainer高阶组件中,当很多这样的input组件都用这个HocContainer高阶组件时,那么它们的值都将保存在这个HocContainer高阶组件中
代理方式之 包装组件
const HocStyleComponent = (WrappedComponent, style) => class extends React.Component{ render() { return () } }
import HocStyleComponent from './HocStyleComponent';const colorSytle ={color:'#ff5555'}const newComponent = HocStyleComponent(SampleComponent, colorSytle);
-
代理方式下WrappedComponent会经历一个完整的生命周期,产生的新组件和参数组件是两个不同的组件,一次渲染,两个组件都会经历各自的生命周期
-
而在继承方式下,产生的新组件和参数组件合二为一,super.render只是生命周期中的函数,变成一个生命周期。
继承方式之 操纵prop
const HOCPropsComponent = (WrappedComponent) => class extends WrappedComponent{ render() { const elementsTree = super.render(); let newProps = { color: (elementsTree && elementsTree.type === 'div') ? '#fff': '#ff5555' }; const props = Object.assign({}, elementsTree.props, newProps) const newElementsTree = React.cloneElement(elementsTree,props,elementsTree.props.children) return newElementsTree } }
这样就传入了新的props
React.cloneElement( element, [props], [...children])
克隆并返回一个新的 ReactElement ,新返回的元素会保留有旧元素的 props、ref、key,也会集成新的 props。