React复习(8):高阶组件应用(操作props)


前言

一个项目中往往会包含很多相似的组件,既然组件基本相似,我们为什么不能像定义函数一样将其也定义成一种方法,我们调用这个方法,根据我们传入的参数返回给我们需要的组件,于是便涉及到了本文内容:高阶组件

一、前篇

我们需要两个组件,分别显示奇数和偶数,正常思路如下:

import React,{Component} from 'react'


class H1 extends Component{
  constructor(props){
    super(props)
    this.state={
      arr:[]
    }
  }
  render(){
    console.log(this.state.arr)
    return(
      <div>
        <ul>
          <p>H1</p>
          {this.state.arr.map((item,index)=>{
            return <li key={index}>{item}</li>
          })}
          </ul>
      </div>
    )
  }
  componentDidMount(){
    var {arr}=this.props
    this.setState(
      {
        arr:arr.filter((item,index)=>{
          return item%2==0
        })
      }
    )
  }
}

class H2 extends Component{
  constructor(props){
    super(props)
    this.state={
      arr:[]
    }
  }
  render(){
    console.log(this.state.arr)
    return(
      <div>
        <ul>
          <p>H2</p>
          {this.state.arr.map((item,index)=>{
            return <li key={index}>{item}</li>
          })}
          </ul>
      </div>
    )
  }
  componentDidMount(){
    var {arr}=this.props
    this.setState(
      {
        arr:arr.filter((item,index)=>{
          return item%2==1
        })
      }
    )
  }
}


class App extends Component{
  constructor(props){
    super(props)
    this.state={
      arr:[1,2,3,4,5,6,7,8,9],
    }
  }
  render(){
    return(
      <div>
          <H1 arr={this.state.arr}></H1>
          <H2 arr={this.state.arr}></H2>
      </div>
    )
  }
}

export default App;

不难发现,H1,H2两个组件除了名字和数组求法,其他一摸一样。这让我们不由得想到了函数,为了减少代码量,提高编码效率,我们可以封装一个函数,根据传入的参数,返回给我们组件。

二、高阶组件

高阶组件:用函数包装一个组件并可以生成新的组件。
高阶组件的意义:
   1.重复利用代码,提取公共部分逻辑,利用高阶组件返回。
   2.修改react组件行为
高阶组件实现方式:
   1.代理方式
   2.继承方式
代理方式应用场景:
   1.操纵props
   2.访问ref
   3.抽离状态
   4.包装组件

我们要写的是一个可以返回一个新的组件的函数,所以基本框架如下:


function H(WrapComponent) {
  return class NewComponent extends Component{

  }
  
}

既然里面返回的是一个新的组件,里面的内容和我们平时写的也就没什么区别:

function H(WrapComponent) {
  return class NewComponent extends Component{
     constructor(props){
       super(props)
     }
     render(){
       return(
         <div></div>
       )
     }
     componentDidMount(){
       
     }
  }
}

重点来了,高阶组件视图部分写法:
在这里插入图片描述
这里传递的arr是传递给新生成的(返回的)组件,给他们传递处理后的数据,然后由他们自身进行渲染。
到此,我们的H1,和H2就可以被H()函数封装如下:

H1=H(H1)
H2=H(H2)

然后就是函数中的逻辑,这里我们要区别两种组件的计算,传入参数boolean,如果值是true,做取偶数操作,否则做取奇数操作,函数如下:


function H(WrapComponent,boolean) {
  return class NewComponent extends Component{
     constructor(props){
       super(props)
       this.state={
         newArr:[]
       }
     }
     render(){
       return(
         <div>
           <WrapComponent arr={this.state.newArr}></WrapComponent>
         </div>
       )
     }
     componentDidMount(){
        var {arr}=this.props
        if(boolean){
          arr=arr.filter((item,index)=>{
            return item%2==0
          })
        }
        else {
          arr=arr.filter((item,index)=>{
            return item%2==1
          })
        }
        this.setState({
          newArr:arr
        })
      }
  }
  
}

相应的H1、H2调用函数时也要传入boolean参数:

  H1=H(H1,true)
  H2=H(H2,false)

然后因为在H函数中已经定义了我们需要的逻辑,所以,H1、H2组件中逻辑部分可以删掉
最终App.js如下:

import React,{Component} from 'react'


function H(WrapComponent,boolean) {
  return class NewComponent extends Component{
     constructor(props){
       super(props)
       this.state={
         newArr:[]
       }
     }
     render(){
       return(
         <div>
           <WrapComponent arr={this.state.newArr}></WrapComponent>
         </div>
       )
     }
     componentDidMount(){
       var {arr}=this.props
        if(boolean){
          arr=arr.filter((item,index)=>{
            return item%2==0
          })
        }
        else {
          arr=arr.filter((item,index)=>{
            return item%2==1
          })
        }
        this.setState({
          newArr:arr
        })
      }
  }
  
}

class H1 extends Component{
  constructor(props){
    super(props)
  }
  render(){
    return(
      <div>
        <ul>
          <p>H1</p>
          {this.props.arr.map((item,index)=>{
            return <li key={index}>{item}</li>
          })}
          </ul>
      </div>
    )
  }
}

class H2 extends Component{
  constructor(props){
    super(props)
  }
  render(){
    return(
      <div>
        <ul>
          <p>H2</p>
          {this.props.arr.map((item,index)=>{
            return <li key={index}>{item}</li>
          })}
          </ul>
      </div>
    )
  }
}
H1=H(H1,true)
H2=H(H2,false)

class App extends Component{
  constructor(props){
    super(props)
    this.state={
      arr:[1,2,3,4,5,6,7,8,9],
    }
  }
  render(){
    return(
      <div>
          <H1 arr={this.state.arr}></H1>
          <H2 arr={this.state.arr}></H2>
      </div>
    )
  }
}

export default App;


结果:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值