react高阶组件(Higher-Order-Components)

 

定义

高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。

具体而言,高阶组件是参数为组件,返回值为新组件的函数。

 

例子

有下面这样两个组件 

import React, {Component} from 'react'

class Welcome extends Component {
    constructor(props) {
        super(props);
        this.state = {
            username: ''
        }
    }
    componentDidMount() {
        this.setState({
            username: 'LLL'
        })
    }

    render() {
        return (
            <div>welcome {this.state.username}</div>
        )
    }
}

export default Welcom


 

import React, {Component} from 'react'

class Goodbye extends Component {
    constructor(props) {
        super(props);
        this.state = {
            username: ''
        }
    }

    componentDidMount() {
        this.setState({
            username: 'LLL'
        })
    }

    render() {
        return (
            <div>goodbye {this.state.username}</div>
        )
    }
}

export default Goodb

我们发现,这两个组件中存在大量的相似代码,因此,我们可以通过高阶组件(一个函数,且该函数接受一个组件作为参数,并返回一个新的组件)来解决这个问题

import React, { Component } from 'react';

export default (WrappedComponent) => {
  class NewComponent extends Component {
    constructor() {
      super();
      this.state = {
        username: '',
      };
    }

    componentWillMount() {
      this.setState({
        username: 'LLL',
      });
    }

    render() {
      return <WrappedComponent username={this.state.username} />;
    }
  }

  return NewComponent;

这样我们就能简化Welcome组件和Goodbye组件。

import React, { Component } from 'react';
import wrapWithUsername from './wrapWithUsername';

class Welcome extends Component {
  render() {
    return (
      <div>
        welcome
        {this.props.username}
      </div>
    );
  }
}

Welcome = wrapWithUsername(Welcome);

export default Welcom

 

import React, { Component } from 'react';
import wrapWithUsername from './wrapWithUsername';

class Goodbye extends Component {
  render() {
    return (
      <div>
        goodbye
        {this.props.username}
      </div>
    );
  }
}

Goodbye = wrapWithUsername(Goodbye);

export default Goodby

本例中,高阶组件就是把username通过props传递给目标组件了。目标组件只管从props里面拿来用就好了。

 

应用

 

属性代理(Props Proxy)

可以说是对组件的包裹,在包裹的过程中对被包裹的组件做了点什么(props的处理,把基础组件和其他元素组合),然后返回,这就成了一个高阶组件。

 

1、props的处理

 

如withRouter

 

2、把基础组件和其他元素组合

 

 出于操作样式、布局或其它的考虑,可以将 基础组件与其它组件包裹在一起。一些相对简单的用法也可以使用正常的父组件来实现,只是使用高阶组件可以获得更多的灵活性。也利于组件的抽象和复用。

export default (WrappedComponent) => {
  class NewComponent extends Component {
    constructor() {
      super();
      this.state = {
        username: '',
      };
    }
    
    componentWillMount() {
      this.setState({
        username: 'LLL',
      });
    }

    render() {
      return (
          <div style={{background:'pink'}}>
            <WrappedComponent username={this.state.username} />
          </div>
      );
    }
  }

  return NewComponent;
}

 

arm框架中的createBundle组件就是很好的一个应用

 

反向继承 (Inheritance Inversion)

可以理解成是组装,和属性代理不同的是,反向继承是继承自基础组件,所有很自然,它可以直接获取基础组件的props,操作基础组件的state。

 

1、渲染劫持

 

所谓渲染劫持就是,高阶组件控制了基础组件渲染生成的结果,因为基础组件的渲染被控制,高阶组件就可以对它做点什么。。。比如:

 

(1)、看心情(根据条件),控制渲染的结果;

(2)、改变dom树的样式;

(3)、改变基础组件中一下被渲染元素的props;

(4)、操作dom树中的元素。

 

2、操作state 

 

高阶组件可以读取、编辑和删除 基础组件 实例的 state,如果你需要,你也可以给它添加更多的 state。需要注意的是,这会搞乱基础组件 的 state,导致你可能会破坏某些东西。所以,要限制高阶组件读取或添加 state,添加 state 时应该放在单独的命名空间里,而不是和基础组件的 state 混在一起。

 

这个就是根据基础组件的state.name来决定要不要渲染。

export default (BaseComponent) => {
  return class Enhancer extends BaseComponent{
    render() {
      return this.state.name === 'NNN' ? super.render() : null;
    }
  }
}

 

资料

https://react.docschina.org/docs/higher-order-components.html

https://zhuanlan.zhihu.com/p/34648434

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值