React高阶组件HOC(二)代理方式的高阶组件

上文提到react高阶组件的基本概念以及基本使用方式,下面将介绍高阶组件的应用方式。

代理方式的高阶组件

返回的新组件直接继承于React.Component类,新组件作为传入组件的一个代理,在新组件中渲染出被包裹组件。除了高阶组件自己要做的事情以外,其余全部由被包裹组件来做。
其有四种操作:

1、操纵props。
2、访问ref。
3、抽取状态。
4、包装组件。


1.操纵props:
我们拿组件B来做演示,给B加一个属性name。

import React from 'react';
import B from './components/B'
import C from './components/C'
import './App.css';

class App extends React.Component {

  render() {
    return (
      <div>
        <B name='李雷' />
        <C />
      </div>
    );
  }
}

在B组件中把name通过props显示出来,但是发现上面并未对sex属性赋值,我们可以在高阶组件中进行传入。

import React, { Component } from 'react'
import A from './A'

@A
class B extends Component {
  render() {
    console.log(this.props)
    return (
      <div>
        <div>这是组件B</div>
        <div>我的名字:{ this.props.name }</div>
        <div>我的性别:{ this.props.sex }</div>
      </div>
    )
  }
}

export default B

首先把根节点的props透传入组件B中,在添加一个新的属性sex。

import React, { Component } from 'react'

export default function A(WrappedComponent) {
  return class A extends Component {
    render() {
      return (
        <div className="box">
          <div>我是公共组件A的内容</div>
          <WrappedComponent {...this.props} sex={'男'} />
        </div>
      )
    }
  }
}

最终达到我们操作props的要求:


2.访问ref:
通过ref访问调用C的实例


import React, { Component } from 'react'

export default function A(WrappedComponent) {
  return class A extends Component {
    refContent(instance) {
      instance.putOutComponent && console.log(instance.putOutComponent())
    }
    render() {
      return (
        <div className="box">
          <div>我是公共组件A的内容</div>
          <WrappedComponent { ...this.props } sex={ '男' } ref={ this.refContent } />
        </div>
      )
    }
  }
}

在C中加入putOutComponent方法

import React, { Component } from 'react'
import A from './A'

class C extends Component {
  putOutComponent() {
    return '这是组件C'
  }

  render() {
    console.log(this.props)
    return (
      <div>这是组件C</div>
    )
  }
}

export default A(C)

控制台中显示组件C中内容方法,这样可以控制所有被包裹组件,以便与业务扩展。


3.抽取状态:
把input的value值和onInputChange方法从高阶组件中以props方式传入。

import React, { Component } from 'react'
import A from './A'

@A
class B extends Component {

  render() {
    return (
      <div>
        <input type='text' {...this.props} />
        <br />
        <div>这是组件B</div>
        <div>我的名字:{ this.props.name }</div>
        <div>我的性别:{ this.props.sex }</div>
      </div>
    )
  }
}

export default B

设置newProps把value值和onInputChange传入,当输入内容改变时便会触发高阶组件onInputChange方法从而获取改变值的内容,同样可以在C组件中加入input在A高阶组件中进行控制。

import React, { Component } from 'react'

export default function A(WrappedComponent) {
  return class A extends Component {
    constructor(props) {
      super(props)
      this.state = {
        value: ''
      }
    }

    refContent(instance) {
      instance.putOutComponent && console.log(instance.putOutComponent())
    }

    onInputChange = (e) => {
      console.log(e.target.value)
      this.setState({
        value: e.target.value
      })
    }

    render() {
      const newProps = {
        value: this.state.value,
        onInput: this.onInputChange
      }
      return (
        <div className="box">
          <div>我是公共组件A的内容</div>
          <WrappedComponent { ...this.props } sex={ '男' } ref={ this.refContent } {...newProps} />
        </div>
      )
    }
  }
}

4.包装组件:
包装组件指我们可以在高阶组件中设置公共部分,<div>我是公共组件A的内容</div>这里就是对组件的包装。

return (
        <div className="box">
          <div>我是公共组件A的内容</div>
          <WrappedComponent { ...this.props } sex={ '男' } ref={ this.refContent } {...newProps} />
        </div>
      )

以上就是代理方式的高阶组件介绍。

原文链接:segmentfault.com

上一篇:passthru
下一篇:@types/diacritics

相关推荐

  • 🍊仿Element自定义Vue组件库

    (/public/upload/643b972fb2ebd2e6272ff8b16712b205) 前言 🍊 市面上目前已有各种各样的UI组件库,他们的强大毋庸置疑。

    3 天前
  • 🆘 一次理解清楚,为什么使用 React useEffect 中使用 setInterval 获取的值不是最新的

    Intro 这篇文章将通过一个使用 React Hook 常遇到的问题(stale state)入手,尝试理解 Hook 的内部运行逻辑。 废话不多说,直接看示例Sandbox。

    9 天前
  • (vue框架)为element组件赋初始值以后无法更改值得问题

    情况描述:组件未加载时已有初始值,mounted里面加载数据,赋值,渲染以后,组件无法更改内容 data里面已经有这个表单对象的初始值但还是无法修改,之前有过一次,没有给表单绑定对象,所以赋值以后无法...

    1 年前
  • 魔方实时通信一对一音视频组件

    魔方实时通信/协作引擎(Web SDK)是一个全能力的实时云端协作引擎 魔方实时通信,请点击这个(https://www.shixincube.com/) 继上一个im聊天组件增加了发动语音,语音...

    2 年前
  • 高频数据交换下Flutter与ReactNative的对比

    (标题图片来自网络,侵删) 后端使用go写的socketio服务模拟期货行情数据,每10ms推送10条行情数据 ReactNative已经尽力优化了。 Flutter由于没fluttersock...

    2 年前
  • 高阶组件之属性代理

    新组件类继承子React.component类,对传入的组件进行一系列操作,从而产生一个新的组件,达到增强组件的作用 操作props 访问ref 抽取state 封装组件 ...

    1 年前
  • 高阶组件HOC - 小试牛刀

    1. 前言 老毕曾经有过一句名言,叫作“国庆七天乐,Coding最快乐~”。所以在这漫漫七天长假,手痒了怎么办?于是乎,就有了接下来的内容。。。 2. 一个中心 今天要分享的内容有关高阶组件...

    2 年前
  • 高阶组件 + New Context API = ?

    1. 前言 继上次小试牛刀(https://github.com/SmallStoneSK/Blog/issues/6)尝到高价组件的甜头之后,现已深陷其中无法自拔。。。

    2 年前
  • 高阶函数的使用

    问题 字节跳动面试时问题:原函数例如fetchData是一个异步函数,尝试从服务器端获取一些信息并返回一个Promise。写一个新的函数可以自动重试一定次数,并且在使用上和原函数没有区别。

    1 年前
  • 高阶函数应用之柯里化与反柯里化

    背景 在 JavaScript 中,柯里化和反柯里化是高阶函数的一种应用,在这之前我们应该清楚什么是高阶函数,通俗的说,函数可以作为参数传递到函数中,这个作为参数的函数叫回调函数,而拥有这个参数的函数...

    7 个月前

官方社区

扫码加入 JavaScript 社区