资讯专栏INFORMATION COLUMN

当初要是看了这篇,React高阶组件早会了

Yi_Zhi_Yu / 1720人阅读

摘要:也就是说,如果能处理名为的这个高阶组件返回的组件则完全无视这个。先展示我是一个组件,我设置了两秒,之后展示倒计时完成

概况: 什么是高阶组件?
高阶部件是一种用于复用组件逻辑的高级技术,它并不是 React API的一部分,而是从React 演化而来的一种模式。 具体地说,高阶组件就是一个接收一个组件并返回另外一个新组件的函数!

这是官方文档说的,我没有截全,因为后面的解释会造成误解,但简单讲高阶组件(函数)就好比一个加工厂,同样的,屏幕、cpu、扬声器、键盘按键、外壳、电池,小米手机工厂组装完就是小米手机,魅族手机组装完就是魅族手机,基本材料都是相同的,不同工厂(高阶组件)有不同的实现及产出,当然这个工厂(高阶组件)也可能是针对某个基本材料的处理。
总之产出的结果拥有了输入组件不具备的功能,输入的组件可以是一个组件的实例,也可以是一个组件类,还可以是一个无状态组件的函数。

解决什么问题?

随着项目越来越复杂,开发过程中,多个组件需要某个功能,而且这个功能和页面并没有关系,所以也不能简单的抽取成一个新的组件,但是如果让同样的逻辑在各个组件里各自实现,无疑会导致重复的代码。比如页面有三种弹窗一个有title,一个没有,一个又有右上角关闭按钮,除此之外别无它样,你总不能整好几个弹窗组件吧,这里除了tilte,关闭按钮其他的就可以做为上面说的基本材料。

高阶组件总共分为两大类

代理方式

操纵prop

访问ref(不推荐)

抽取状态

包装组件

继承方式

操纵生命周期

操纵prop

代理方式之 操纵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;

上面HocRemoveProp高阶组件中,所做的事情和输入组件WrappedComponent功能一样,只是忽略了名为user的prop。也就是说,如果WrappedComponent能处理名为user的prop,这个高阶组件返回的组件则完全无视这个prop。

const { user, ...otherProps } = this.props;

这是一个利用es6语法技巧,经过上面的语句,otherProps里面就有this.props中所有的字段除了user.
假如我们现在不希望某个组件接收user的prop,那么我们就不要直接使用这个组件,而是把这个组件作为参数传递给HocRemoveProp,然后我们把这个函数的返回结果当作组件来使用
两个高阶组件的使用方法:

const  newComponent = HocRemoveProp(SampleComponent);
const  newComponent = HocAddProp(SampleComponent,"1111111");

也可以利用decorator语法糖这样使用

import React, { Component } from "React";

@HocRemoveProp 
class 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 
    }
  }
@HocContainer
class 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);

-代理方式的生命周期的过程类似于堆栈调用:
didmount 一> HOC didmount 一>(HOCs didmount) 一>(HOCs will unmount) 一>HOC will unmount一>unmount

在说继承方式之前先看一个例子
const MyContainer = (WrappedComponent) =>
  class extends WrappedComponent {
    render() {
      return super.render();
    }
  }

这个例子很简单,相当于把WrappedComponent组件的render方法,通过super.render()方法吐到了MyContainer 中,可以顺序调用。

继承方式的生命周期的过程类似于队列调用:

didmount 一> HOC didmount 一>(HOCs didmount) 一>will unmount一>HOC will unmount一> (HOCs will unmount)

代理方式下WrappedComponent会经历一个完整的生命周期,产生的新组件和参数组件是两个不同的组件,一次渲染,两个组件都会经历各自的生命周期,

在继承方式下,产生的新组件和参数组件合二为一,super.render只是生命周期中的函数,变成一个生命周期。

来看下面的例子你就会明白了。

继承方式之 操纵生命周期(渲染劫持)

首先创建一个高阶,在创建一个使用高阶组件的组件,也就是是输入组件,最后我在改变这个输入组件props

import * as React from "react";

const HocComponent = (WrappedComponent) =>
  class MyContainer extends WrappedComponent {
    render() {
      if (this.props.time && this.state.success) {
        return super.render()
      }
      return 
倒计时完成了...
} }

这个高阶组件会直接读取输入组件中的props,state,然后控制了输入组件的render展示
只有在props.time和state.success同时为真的时候才会展示

import * as React from "react";
import HocComponent from "./HocComponent"

@HocComponent

class DemoComponent extends React.Component {
  constructor(props) {
    super(props);
   this.state = {
    success: true,
   };
 }
  render() {
    return   
我是一个组件
} } export default DemoComponent;

然后调用,递减time数值直到变为0

最后页面的效果就是,当然他不是循环的。先展示”我是一个组件“,我设置了两秒,之后展示”倒计时完成“.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/98314.html

相关文章

  • 高阶组件HOC - 小试牛刀

    摘要:因为这个高阶函数,赋予了普通组件一种呼吸闪烁的能力记住这句话,圈起来重点考。其实,高阶组件就是把一些通用的处理逻辑封装在一个高阶函数中,然后返回一个拥有这些逻辑的组件给你。 原文地址:https://github.com/SmallStoneSK/Blog/issues/6 1. 前言 老毕曾经有过一句名言,叫作国庆七天乐,Coding最快乐~。所以在这漫漫七天长假,手痒了怎么办?于是...

    lookSomeone 评论0 收藏0
  • 个人分享--web前端学习资源分享

    摘要:前言月份开始出没社区,现在差不多月了,按照工作的说法,就是差不多过了三个月的试用期,准备转正了一般来说,差不多到了转正的时候,会进行总结或者分享会议那么今天我就把看过的一些学习资源主要是博客,博文推荐分享给大家。 1.前言 6月份开始出没社区,现在差不多9月了,按照工作的说法,就是差不多过了三个月的试用期,准备转正了!一般来说,差不多到了转正的时候,会进行总结或者分享会议!那么今天我就...

    sherlock221 评论0 收藏0
  • 初识react高阶组件

    摘要:也明确了大数据时代,前端所应该具备的职业素养高阶组件高阶组件,高阶组件就是一个组件包裹着另外一个组件中两种的实现方法中两种的实现方法返回的类继承了。之所以被称为是因为被继承了,而不是继承了。在这种方式中,它们的关系看上去被反转了。 前言 最近一直再做数据可视化,业务的理解,数据的理解确实如数据可视化要求的一样,有了更多的理解。但是技术上还停留在echart,Hchart, 画图上。正好...

    IamDLY 评论0 收藏0
  • React构建个人博客

    摘要:兄弟组件之间无法直接通信,它们需要利用同一层的上级作为中转站。在两个地方会用到,一是通过提交后需要拿到里面的数据,二是利用监听到发生变化后调用它来获取新的数据。 前言 在学习react的过程中,深深的被react的函数式编程的模式所吸引,一切皆组件,所有的东西都是JavaScript。React框架其实功能很单一,主要负责渲染的功能,但是社区很活跃,衍生出了很多优秀的库和工具。个人觉得...

    lyning 评论0 收藏0

发表评论

0条评论

Yi_Zhi_Yu

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<