前言:React有两类组件,函数组件和类组件,但是在类组件的书写过程中会有大量的冗余代码,而且要处理在整个类里面this的问题,但是只有在类组件里面有state和生命周期函数这两个特性。同时,为了解决在组件之间复用状态逻辑很难、复杂组件变得难以理解等问题,React在16.8中新增了Hook。Hook就是一个特殊的函数,它可以让你“钩入”React的特性

1.Hook就是js函数,使用有以下规则

        1)只能在函数最外层调用Hook。不要在循环,条件判断或者子函数中调用

        2)只能在react的函数组件中调用Hook(还有一个地方可以调用,就是自定义的Hook中)

2.useState(一个可以让你在函数组件中添加state的Hook)的使用

import {useState} from 'react'
const [n, setN] = useState(0)

useState的参数只有一个,就是初始state,不像Class,我们可以根据实际需要使用数字、字符串来对它进行赋值,不一定是对象。函数返回值是一个数组,我们使用解构赋值取出了返回值中的两个成员。

第一个(n),会把他当作变量存储在state中,而第二个(setN)就是对该状态的修改方法,类似于class中的this.setState(),修改完state,React会重新渲染组件,并把最新的n传给他。

这里需要注意的是,如果把多个state变量分为一组,里面有多个成员,当某一个成员更新时,不像class里面的setState,去自动合并其他成员,而是替换。

3.useEffect的使用

        useEffect模拟了3个生命周期函数,分别是componentDidMount,  componentDidUpdate,  componentWillUnmount.

import {useEffect} from 'react'

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

useEffect函数有2个参数,第一个参数是一个回调,当页面第一次加载完,或者组件重新渲染完都会去执行这个回调。第二个参数是一个数组,作用是:如果在里面放了一个state,组件重新渲染是由当前state被修改引起的,那么就会执行回调函数,不写的话,默认所有state变化引起的组件渲染都会执行这个回调,写一个空数组就是即使组件重新渲染了,也不会执行回调。

另外,回调函数的返回值也是一个回调函数,当某一个组件被销毁时,就会去调用返回值回调函数,模拟出了componentWillUnmount。

下面是一个完整例子

import React, {useEffect, useState} from 'react'

export default function Goods() {
    const [n, setN] = useState(0)
    const [m, setM] = useState(1)
    useEffect(() => {
        console.log('Effect......')
        return () => {
            console.log('我将被销毁')
        }
    }, [])
    return (
        <div>
            <button onClick={() => {setN(n+1)}}>+</button>
        </div>
    )
}

除此之外,还有一些使用频率较低但是很有用的Hook,useContext让你不使用组件嵌套就可以订阅React的Context;useReducer可以让你通过reducer 来管理组件本地的复杂 state