react高阶组件的使用

  1. react的组件树结构

根组件

  • 路由组件
    • 展示组件
      • 链接组件
      • 链接组件
    • 路由规则
      • / 重定向(首页)
    • 路由规则
      • /page1 父组件1(和路径绑定的页面1)
        • 子组件1(计时器1)
        • 子组件2(计时器2)
    • 路由规则
      • /page2 父组件2(和路径绑定的页面2)
        • 高阶组件(计时器逻辑)
          • 原始组件3(计时器ui3)
        • 高阶组件(计时器逻辑)
          • 原始组件4(计时器ui4)
  1. 子组件的定义和调用
1.定义计时器1
export default function Timer1(){
 const [time,setTime]=useState(0)
 
 useEffect(()=>{
  const interval=setInterval(()=>{
   setTime(preTime=>preTime+1)
  },1000)
  return ()=>{
   clearInterval(interval)
  }
 },[])
 
 return(
  <div>计时器1{time}</div>
 )
}
2.定义计时器2
export default function Timer2(){
 const [time,setTime]=useState(0)
 
 useEffect(()=>{
  const interval=setInterval(()=>{
   setTime(preTime=>preTime+1)
  },1000)
  return ()=>{
   clearInterval(interval)
  }
 },[])
 
 return(
  <div>计时器2{time}</div>
 )
}
3.调用两个计时器
export default function Page1(){
 return (
  <div>
   <Timer1/>
   <Timer2/>
  </div>
 )
}

优化:复用整个函数组件

//将ui不同的部分作为父子组件的参数,这样可以复用子组件的逻辑
1.定义计时器
export default function Timer(props){
 const [time,setTime]=useState(0)
 
 useEffect(()=>{
  const interval=setInterval(()=>{
   setTime(preTime=>preTime+1)
  },1000)
  return ()=>{
   clearInterval(interval)
  }
 },[])
 
 return(
  <div>{props.name}{time}</div>
 )
}
2.调用计时器
export default function Page1(){
 return (
  <div>
   <Timer name={"计时器1"}/>
   <Timer name={"计时器2"}/>
  </div>
 )
}
  1. 复用类组件逻辑:高阶组件的定义和调用
1.定义原始组件:定时器ui1和定时器ui2
export class TimerUI1 extends Component{
 render(){
  return(
   <div>计时器1{this.props.time}</div>
  )
 }
}

export class TimerUI2 extends Component{
 render(){
  return(
   <div>计时器2{this.props.time}</div>
  )
 }
}
2.定义高阶组件:定时器逻辑
export default function withTimerLogic(TimerUI){
 return class TimerLogic extends Component{
  state={
   time:0
  }
  interval=null
  //在类组件里声明的是属性,所以不需要写let或者const
  //在类组件外或者函数组件里或者render方法里声明的是变量,所以需要写let或者const
  
  componentDidMount(){
   this.interval=setInterval(()=>{
    this.setState(prevState=>({time:prevState.time+1}))
   },1000)
  }
  
  componentWillUnmount(){
   clearInterval(this.interval)
  }
  
  render(){
   return(
    <TimerUI time={this.state.time} {...this.props}/>
    //爷:Page2,父:TimeLogic,子:TimerUI
    //time是父亲创造,传递给孩子。props是爷爷传递给父亲传递给孩子
   )
  }
 }
}
3.调用增强组件:定时器
const Timer1=withTimerLogic(TimerUI1)
const Timer2=withTimerLogic(TimerUI2)
export default class Page2 extends Component{
 render(){
  return(
   <div>
    <Timer1/>
    <Timer2/>
   </div>
  )
 }
}

优化:进一步复用类组件ui

1.定义原始组件:定时器ui
export class TimerUI extends Component{
 render(){
  return(
   <div>{this.props.name}{this.props.time}</div>
  )
 }
}
2.定义高阶组件:定时器逻辑
export default function withTimerLogic(TimerUI){
 return class TimerLogic extends Component{
  state={
   time:0
  }
  interval=null
  //在类组件里声明的是属性,所以不需要写let或者const
  //在类组件外或者函数组件里或者render方法里声明的是变量,所以需要写let或者const
  
  componentDidMount(){
   this.interval=setInterval(()=>{
    this.setState(prevState=>({time:prevState.time+1}))
   },1000)
  }
  
  componentWillUnmount(){
   clearInterval(this.interval)
  }
  
  render(){
   return(
    <TimerUI time={this.state.time} {...this.props}/>
    //爷:Page2,父:TimeLogic,子:TimerUI
    //time是父亲创造,传递给孩子。props是爷爷传递给父亲传递给孩子
   )
  }
 }
}
3.调用增强组件:定时器
const Timer=withTimerLogic(TimerUI)
export default class Page2 extends Component{
 render(){
  return(
   <div>
    <Timer name={"计时器1"}/>
    <Timer name={"计时器2"}/>
   </div>
  )
 }
}
  1. 配置路由规则
  • App.js
import React,{Component} from 'react'
import {BrowserRouter as Router,Link,Switch,Route} from 'react-router-dom'
import {Layout,Menu} from 'antd'
import Home from './Home'
import Page1 from './Page1'
import Page2 from './Page2'
const {Header,Content}=Layout

export default class App extends Component{
 render(){
  return(
   <Router>
    <Layout>
     <Header>
      <Menu theme="dark" mode="horizontal" defaultSelectedKeys={["1"]}>
       <Menu.Item key="1">
        <Link to="/">首页</Link>
       </Menu.Item>
       <Menu.Item key="2">
        <Link to="/page1">页面1</Link>
       </Menu.Item>
       <Menu.Item key="3">
        <Link to="/page2">页面2</Link>
       </Menu.Item>
      </Menu>
     </Header>
     <Content>
      <Switch>
       <Route path="/" component={Home} exact />
       //如果不加exact,点击页面1和页面2也都会跳转到首页
       <Route path="/page1" component={Page1} />
       <Route path="/page2" component={Page2} />
      </Switch>
     </Content>
    </Layout>
   </Router>
  )
 }
}
  • Home.js
import React from 'react'
import {Layout} from 'antd'
const {Content}=Layout

export default Home extends Component{
 render(){
  return(
   <Content>这是首页</Content>
  )
 }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值