首页 > 其他 > 详细

React高阶组件

时间:2019-09-02 22:26:46      阅读:87      评论:0      收藏:0      [点我收藏+]

本质

本质是函数,将组件作为接收参数,返回一个新的组件。HOC本身不是React API,是一种基于React组合的特而形成的设计模式。

解决的问题(作用)

  • 一句话概括:功能的复用,减少代码冗余
  • 进一步解释:在实际情况中,多个组件可能会做某些相同的事情,有着相同的功能,存在大量的代码冗余。我们可以将这部分功能拆分出来,每个组件尽量只保留自己独有的作用,通过HOC生成我们最终需要的组件。

实现方法:

无论哪种方法,都是在HOC函数内定义新的组件,在新的组件内做一些公共的功能和事情

  1. 属性代理
  2. 反向继承

属性代理

这是最常规的写法,原理等同于ES7装饰器、Python装饰器。函数传入的参数,除了原组件,还可以定义其他的参数,通过这些参数来区别每个实际组件。比如,公共的功能是获取数据。获取数据这件事情是相同的,但获取的内容不同。如何决定最后生成的组件获取各自指定的内容呢?通过函数传参。

// 示例用localstorage代替如网络请求等的异步操作
localStorage.setItem("comment","asuiklfhs");  
localStorage.setItem("read","123");

class Comment extends React.Component {

   render() {
      return (
         <div>
            {this.props.data}
         </div>
      )
   }
}

class Read extends React.Component {

   render() {
      return (
         <div>
            {this.props.data}
         </div>
      )
   }
}

const HOCTest = (key) => {
   return (WrappedComponent) => {
      return class NewComponent extends React.Component{

         constructor(props) {
            super(props);
            this.state = {
               data: ‘‘
            };
         }

         componentDidMount() {
            const data = localStorage.getItem(key);
            this.setState({
               data
            });
         }

         render() {
            console.log(this.myRef);
            return (
               <div ref={(e)=>{this.myRef = e;}}>
                  <WrappedComponent {...this.props} data={this.state.data} />
               </div>
            );
         }
      }
   }
};

const CommentNew = HOCTest("comment")(Comment);  // HOC生成新组件
const ReadNew = HOCTest("read")(Read);

class Root extends React.Component {
   render() {
      return (
         <div className="App">
            Hello World
            <CommentNew/>
            <ReadNew/>
         </div>
      );
   }
}

在这里,React第三方的组件库通常使用 函数柯里化 的写法。对于使用者来说,改变了调用函数时的传参方式,更加容易理解。即:原本调用函数wrapper(Component, params1, params2)  柯里化后调用wrapper(params1,params2)(Component)

属性代理常见的作用:

  1. 操作props
  2. 通过Refs访问组件实例
  3. 提取state
  4. 组合更多的html元素

反向继承

顾名思义,就是将返回的组件继承了原组件。它允许生成的组件通过this获取原组件,意味着可以获取到state,props,生命周期钩子,以及render

localStorage.setItem("comment","asuiklfhs");
localStorage.setItem("read","123");

class Comment extends React.Component {
   constructor(props){
      super(props);
      this.state = {id:"comment"}
   }

   componentDidMount() {
      console.log("Comment DidMount");
   }

   render() {
      return (
         <div>
            {this.props.data}
         </div>
      )
   }
}

class Read extends React.Component {
   constructor(props){
      super(props);
      this.state = {id:"read"}
   }

   render() {
      return (
         <div>
            {this.props.data}
         </div>
      )
   }
}

const HOCTest = (key) => {
   return (WrappedComponent) => {
      return class NewComponent extends WrappedComponent{

         componentDidMount() {
            console.log("HOC DidMount");
            const data = localStorage.getItem(key);
            this.setState({
               ...this.state,
               data
            });
         }

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

const CommentNew = HOCTest("comment")(Comment);
const ReadNew = HOCTest("read")(Read);

class Root extends React.Component {

   render() {
      return (
         <div className="App">
            Hello World
            <CommentNew/>
            <ReadNew/>
         </div>
      );
   }
}

作用:

  1. 渲染劫持。由于新组件可以控制原组件的render方法,可以做各种控制渲染的操作。
  2. 操作state

注意点:

  1. 不要在函数内修改原组件
  2. 使用反向继承方式时,会丢失原本的显示名
  3. 不要在render函数中使用HOC

 

React高阶组件

原文:https://www.cnblogs.com/V587Chinese/p/11444842.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!