React-Hook(2):副作用钩子useEffect


一、简单介绍

useEffect又叫副作用钩子,是React-Hook中的一种,如果说useState获取的是数据和改变状态的方法,那么useEffect就相当于组件的生命周期componentDidMount和componentDidUpdate以及componentWillUnMount.

二、第一个参数

useEffect的第一个参数,可以理解为是在生命周期下我们想要对状态做的处理。
对于点击按钮count++练习,不用钩子代码如下:

class App extends Component{
  constructor(props){
    super(props)
    this.state={
      count:0
    }
  }
  change(){
    this.setState({
      count:++this.state.count
    })
  }
  render(){
    return(
      <div>
        <Text></Text>
        <p>{this.state.count}</p>
        <button onClick={()=>{this.change()}}>Change</button>
      </div>
    )
  }
  componentDidMount(){
    document.title="Count:"+this.state.count
  }
  componentDidUpdate(){
    document.title="Count"+this.state.count
  }
}

这里添加了两个生命周期方法,注意document.tittle的变化。下面改成Hook useState+useEffect的形式:

function Text() {
  var [count,setCount]=useState(0)
  useEffect(()=>{//副作用钩子
    //相当于componentDidMount和componentDidUpdate两个组件
    document.title="Count"+count
  })
  return(
    <div>
      <p>{count}</p>
      <button onClick={()=>{setCount(++count)}}>Add</button>
    </div>
  )
} 
class App extends Component{
  constructor(props){
    super(props)
    this.state={
      count:0
    }
  }
  change(){
    this.setState({
      count:++this.state.count
    })
  }
  render(){
    return(
      <div>
        <Text></Text>
        <p>{this.state.count}</p>
        <button onClick={()=>{this.change()}}>Change</button>
      </div>
    )
  }
  // componentDidMount(){
  //   document.title="Count:"+this.state.count
  // }
  // componentDidUpdate(){
  //   document.title="Count"+this.state.count
  // }
}

再次观察document.title就会发现和刚才的结果一样,说明useEffect相当于两个生命周期函数。
useEffect副作用钩子有两种情况,
1.无需清理的
2.需要清理的

所谓需不需要清理要看,你的组件卸载后是否对整个项目有影响,是否还有程序在运行。对于上面案例,在App组件中将Text组件卸载后将不再有相关程序运行说明此时的组件是无需清理的,而需要清理一般会发生在定时器上,如下情况(直接写hook版本,非hook版本的添加其实就是在componentWillUnMount生命周期函数中添加定时器);

function Text() {
  var [count,setCount]=useState(0)
  useEffect(()=>{//副作用钩子
    //相当于componentDidMount和componentDidUpdate两个组件
    document.title="Count"+count
    var timer=setInterval(() => {
      console.log("Text")
    }, 1000);
    return function(){
      clearInterval(timer)
    }
  })
  return(
    <div style={{border:"1px solid black"}}>
      <p>{count}</p>
      <button onClick={()=>{setCount(++count)}}>Add</button>
    </div>
  )
} 
class App extends Component{
  constructor(props){
    super(props)
    this.state={
      count:0
    }
  }
  change(){
    this.setState({
      count:++this.state.count
    })
  }
  render(){
    return(
      <div>
        {/* <Text></Text> */}
        {this.state.count%2==0?<Text></Text>:""}
        <p>{this.state.count}</p>
        <button onClick={()=>{this.change()}}>卸载Text</button>
      </div>
    )
  }
  // componentDidMount(){
  //   document.title="Count:"+this.state.count
  // }
  // componentDidUpdate(){
  //   document.title="Count"+this.state.count
  // }
}

主要看useEffect传递的第一个参数:
在这里插入图片描述
初始状态(上面是Text组件),右边控制台一直打印:
在这里插入图片描述
点击卸载,后组件内部定时器被清除,不再打印(再次点击Text组件恢复):
在这里插入图片描述
所以从此处看出,一个useEffect代替了三个生命周期:componentDidMount,componentDidUpdate,componentWillUnMount.

三、第二个参数

又称为依赖项,即当前这个useEffect的处理,是想针对哪一个状态进行的,通常以数组形式传入。
例如Text组件要维护两种状态count和str,如果不添加依赖项,那么两种状态任何一个发生改变都会触发处理行为(即useEffect传入的第一个函数参数)添加依赖项如下代码,:

function Text() {
  var [count,setCount]=useState(0)
  var [str,setStr]=useState("ads")
  useEffect(()=>{//副作用钩子
    //相当于componentDidMount和componentDidUpdate两个组件
    document.title="Count"+count+" "+str
    // var timer=setInterval(() => {
    //   console.log("Text")
    // }, 1000);
    // return function(){
    //   clearInterval(timer)
    // }
  },[count])
  return(
    <div style={{border:"1px solid black"}}>
      <p>{count}</p>
      <button onClick={()=>{setCount(++count)}}>Add</button>
       <p>{str}</p>
       <button onClick={()=>{setStr("111111")}}>ChangeStr</button>
    </div>
  )
} 

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值