React Hooks之useEffect

在用Class制作组件时,经常会用生命周期函数,来处理一些额外的事情(副作用:和函数业务主逻辑关联不大,特定时间或事件中执行的动作,比如Ajax请求后端数据,添加登录监听和取消登录,手动修改DOM等等)。在React Hooks中也需要这样类似的生命周期函数,比如在每次状态(State)更新时执行,它为我们准备了useEffect。从这节课开始来认识一下这个useEffect函数。它就像一匹野马,当你没有驯服它时,感觉它很难相处甚至无法掌握;但你驯服它后,你会发现它温顺可爱,让你爱不释手。

Class的方式为计数器增加生命周期函数

为了让你更好的理解useEffect的使用,先用原始的方式把计数器的Demo增加两个生命周期函数componentDidMountcomponentDidUpdate。分别在组件第一次渲染后在浏览器控制台打印出计数器结果和在每次计数器状态发生变化后打印出结果。代码如下:

import React, { Component } from 'react';

class Example3 extends Component {
    constructor(props) {
        super(props);
        this.state = { count:0 }
    }


    componentDidMount(){
        console.log(`ComponentDidMount=>You clicked ${this.state.count} times`)
    }
    componentDidUpdate(){
        console.log(`componentDidUpdate=>You clicked ${this.state.count} times`)
    }

    render() { 
        return (
            

You clicked {this.state.count} times

); } addCount(){ this.setState({count:this.state.count+1}) } } export default Example3;

这就是在不使用Hooks情况下的写法,那如何用Hooks来代替这段代码,并产生一样的效果那。

useEffect函数来代替生命周期函数

在使用React Hooks的情况下,我们可以使用下面的代码来完成上边代码的生命周期效果,代码如下(修改了以前的diamond): 记得要先引入useEffect后,才可以正常使用。

import React, { useState , useEffect } from 'react';
function Example(){
    const [ count , setCount ] = useState(0);
    //---关键代码---------start-------
    useEffect(()=>{
        console.log(`useEffect=>You clicked ${count} times`)
    })
    //---关键代码---------end-------

    return (
        

You clicked {count} times

) } export default Example;

写完后,可以到浏览器中进行预览一下,可以看出跟class形式的生命周期函数是完全一样的,这代表第一次组件渲染和每次组件更新都会执行这个函数。 那这段代码逻辑是什么?我们梳理一下:首先,我们生命了一个状态变量count,将它的初始值设为0,然后我们告诉react,我们的这个组件有一个副作用。给useEffecthook传了一个匿名函数,这个匿名函数就是我们的副作用。在这里我们打印了一句话,当然你也可以手动的去修改一个DOM元素。当React要渲染组件时,它会记住用到的副作用,然后执行一次。等Reat更新了State状态时,它再一词执行定义的副作用函数。

useEffect两个注意点

  1. React首次渲染和之后的每次渲染都会调用一遍useEffect函数,而之前我们要用两个生命周期函数分别表示首次渲染(componentDidMonut)和更新导致的重新渲染(componentDidUpdate)。

  2. useEffect中定义的函数的执行不会阻碍浏览器更新视图,也就是说这些函数时异步执行的,而componentDidMonutcomponentDidUpdate中的代码都是同步执行的。个人认为这个有好处也有坏处吧,比如我们要根据页面的大小,然后绘制当前弹出窗口的大小,如果时异步的就不好操作了。

useEffect 实现 componentWillUnmount生命周期函数

在写React应用的时候,在组件中经常用到componentWillUnmount生命周期函数(组件将要被卸载时执行)。比如我们的定时器要清空,避免发生内存泄漏;比如登录状态要取消掉,避免下次进入信息出错。所以这个生命周期函数也是必不可少的,这节课就来用useEffect来实现这个生命周期函数,并讲解一下useEffect容易踩的坑。

useEffect解绑副作用

学习React Hooks 时,我们要改掉生命周期函数的概念(人往往有先入为主的毛病,所以很难改掉),因为Hooks叫它副作用,所以componentWillUnmount也可以理解成解绑副作用。这里为了演示用useEffect来实现类似componentWillUnmount效果,先安装React-Router路由,进入项目根本录,使用npm进行安装。

npm install --save react-router-dom

然后打开Example.js文件,进行改写代码,先引入对应的React-Router组件。

import { BrowserRouter as Router, Route, Link } from "react-router-dom"

在文件中编写两个新组件,因为这两个组件都非常的简单,所以就不单独建立一个新的文件来写了。

function Index() {
    return 

JSPang.com

; } function List() { return

List-Page

; }

有了这两个组件后,接下来可以编写路由配置,在以前的计数器代码中直接增加就可以了。

return (
    

You clicked {count} times

  • 首页
  • 列表
)

然后到浏览器中查看一下,看看组件和路由是否可用。如果可用,我们现在可以调整useEffect了。在两个新组件中分别加入useEffect()函数:


function Index() {
    useEffect(()=>{
        console.log('useEffect=>老弟,你来了!Index页面')
        )
    return 

JSPang.com

; } function List() { useEffect(()=>{ console.log('useEffect=>老弟,你来了!List页面') }) return

List-Page

; }

这时候我们点击Link进入任何一个组件,在浏览器中都会打印出对应的一段话。这时候可以用返回一个函数的形式进行解绑,代码如下:

function Index() {
    useEffect(()=>{
        console.log('useEffect=>老弟你来了!Index页面')
        return ()=>{
            console.log('老弟,你走了!Index页面')
        }
    })
    return 

JSPang.com

; }

这时候你在浏览器中预览,我们仿佛实现了componentWillUnmount方法。但这只是好像实现了,当点击计数器按钮时,你会发现老弟,你走了!Index页面,也出现了。这到底是怎么回事那?其实每次状态发生变化,useEffect都进行了解绑。

useEffect的第二个参数

那到底要如何实现类似componentWillUnmount的效果那?这就需要请出useEffect的第二个参数,它是一个数组,数组中可以写入很多状态对应的变量,意思是当状态值发生变化时,我们才进行解绑。但是当传空数组[]时,就是当组件将被销毁时才进行解绑,这也就实现了componentWillUnmount的生命周期函数。

function Index() {
    useEffect(()=>{
        console.log('useEffect=>老弟你来了!Index页面')
        return ()=>{
            console.log('老弟,你走了!Index页面')
        }
    },[])
    return 

JSPang.com

; }

为了更加深入了解第二个参数的作用,把计数器的代码也加上useEffect和解绑方法,并加入第二个参数为空数组。代码如下:

function Example(){
    const [ count , setCount ] = useState(0);

    useEffect(()=>{
        console.log(`useEffect=>You clicked ${count} times`)

        return ()=>{
            console.log('====================')
        }
    },[])

    return (
        

You clicked {count} times

  • 首页
  • 列表
) }

这时候的代码是不能执行解绑副作用函数的。但是如果我们想每次count发生变化,我们都进行解绑,只需要在第二个参数的数组里加入count变量就可以了。代码如下:

function Example(){
    const [ count , setCount ] = useState(0);

    useEffect(()=>{
        console.log(`useEffect=>You clicked ${count} times`)

        return ()=>{
            console.log('====================')
        }
    },[count])

    return (
        

You clicked {count} times

  • 首页
  • 列表
) }

这时候只要count状态发生变化,都会执行解绑副作用函数,浏览器的控制台也就打印出了一串=================

以上就是useEffect的全部内容

你可能感兴趣的:(前端)