zoukankan      html  css  js  c++  java
  • React高阶组件

    React高阶组件概述

    • 高阶组件是React中一个很重要且比较复杂的概念,高阶组件在很多第三方库(如Redux)中都被经常使用,在项目中用好高阶组件,可以显著提高代码质量。

    高阶函数的基本概念

    • 函数可以作为参数被传递
    setTimeout(() => {
        console.log('1')
      }, 1000)
    
    
    • 函数可以作为返回值输出
       foo = (x) => {
        return function () {
          return x
        }
      }
    

    高阶组件的基本概念

    • 高阶组件就是接受一个组件作为参数并返回一个新组件的函数。
    • 高阶组件是一个函数,并不是组件。

    为什么需要高阶组件?

    • 多个组件都需要某个相同功能,使用高阶组件减少重复实现。
    • 重复是优秀系统设计的大敌
    • 高阶组件示例: react-redux 中的connect
    export default connect(maoStateToProps, mapDispatchToProps)(Header)
    

    高阶组件的实现

    编写高阶组件

    使用方法一:

    • 实现一个普通组件
    import React from 'react'
    
    export default class Start extends React.Component {
      render () {
        return (
          <div>组件A</div>
        )
      }
    }
    
    • 将普通组件使用函数包裹起来
    import React from 'react'
    
    function A (WrappedComponent) {
      return class Start extends React.Component {
        render () {
          return (
            <div>
              <div>这是组件A</div>
              <WrappedComponent />
            </div>
          )
        }
      }
    }
    
    export default A
    
    • 使用高阶组件
    import React from 'react'
    import a from './A'
    
    class B extends React.Component {
      render () {
        return (
          <div>这是组件B</div>
        )
      }
    }
    
    export default a(B)
    

    使用方法二:类装饰器

    import React from 'react'
    import a from './A'
    @a
    class B extends React.Component {
      render () {
        return (
          <div>这是组件B-</div>
        )
      }
    }
    
    export default B
    

    高阶组件应用

    代理方式的高阶组件

    返回的新组件类直接继承React.Component 类,新组件扮演的角色传入参数组件的一个代理,在新组件的render函数中,被包裹组件渲染出来,除了高阶组件自己要做得工作,其余功能全都转手给了被包裹的组件。

    • 操作props
      高阶组件能改变包裹组件的props,可以做任何的读取、编辑、删除props的一系列操作,甚至可以在高阶组件中自定义事件,然后通过props传递下去。
    // A.js
    import React from 'react'
    
    function A (WrappedComponent) {
      return class Start extends React.Component {
        render () {
          return (
            <div>
              <div>这是组件A</div>
              {this.props.name}
              <WrappedComponent {...this.props} age="18" />
            </div>
          )
        }
      }
    }
    
    export default A
    
    // B.js
    import React from 'react'
    import a from './A'
    
    @a
    class B extends React.Component {
      render () {
        return (
          <div>
            <div>这是组件B:</div>
            <p>我的名字叫:{this.props.name}</p>
            <p>我的年龄是:{this.props.age}</p>
          </div>
        )
      }
    }
    
    export default B
    
    // C.js
    import React from 'react'
    
    class C extends React.Component {
      render () {
        return (
          <div>组件C</div>
        )
      }
    }
    
    export default C
    
    // D.js
    import React from 'react'
    import A from './A'
    import B from './B'
    import C from './C'
    
    class D extends React.Component {
      render () {
        return (
          <div>
            <A />
            <B name='张三' />
            <C />
            <div>这是组件D</div>
          </div>
        )
      }
    }
    
    export default D
    
    • 访问ref
      ref可以自由的操作被包裹组件的元素
      注意:(ref属性非常容易出问题,不推荐使用)
    // A.js
    import React from 'react'
    
    function A (WrappedComponent) {
      return class Start extends React.Component {
        refTest (instance) {
          instance.getName && alert(instance.getName())
        }
        render () {
          const { age, ...otherProps } = this.props
          return (
            <div>
              <div>这是组件A:</div>
              {this.props.name}
              <WrappedComponent {...otherProps} sex='A组件' ref={this.refTest.bind(this)} />
            </div>
          )
        }
      }
    }
    
    export default A
    // C.js
    import React from 'react'
    import a from './A'
    
    @a
    class C extends React.Component {
      getName () {
        return '我是C组件'
      }
      render () {
        return (
          <div>组件C</div>
        )
      }
    }
    
    export default C
    
    • 抽取状态
    // A.js
    import React from 'react'
    
    function A (WrappedComponent) {
      return class Start extends React.Component {
        state = { value: '' }
        inputHandle = (e) => {
          let value = e.target.value
          this.setState({ value })
        }
        render () {
          const newProps = {
            value: this.state.value,
            onInput: this.inputHandle
          }
          return (
            <div>
              <div>这是组件A:{this.state.value}</div>
              <WrappedComponent  {...newProps} />
            </div>
          )
        }
      }
    }
    
    export default A
    // B.js
    import React from 'react'
    import a from './A'
    
    @a
    class B extends React.Component {
    
      render () {
        return (
          <div>
            <div>这是组件B:{this.props.value}</div>
            <input  {...this.props} />
          </div>
        )
      }
    }
    
    export default B
    
    • 包装组件

    继承方式的高阶组件

    • 采用继承关联作为参数的组件和返回的组件,假如传入的组件参数是WrappedComponent,那么返回的组件就直接继承自WrappedComponent
    export default () => WrappedComponent => class A extends WrappedComponent {
      render () {
        const { user, otherProps } = this.props
        this.props = otherProps
        return super.render()
      }
    }
    
    • 操纵porps

    • 操纵 生命周期函数

    高阶组件显示名

  • 相关阅读:
    学习HTML-第一章HTML基础
    javascript中apply 和 call 的区别
    数据库
    贝叶斯公式的直观理解(先验概率/后验概率)
    4-决策树
    消息队列
    RESTful api 设计规范
    MySql索引
    MySQL并发控制
    MySQL三层逻辑架构
  • 原文地址:https://www.cnblogs.com/liea/p/11823740.html
Copyright © 2011-2022 走看看