Hook FAQ

2020-07-13  本文已影响0人  skoll

hook并不能覆盖所有class所有使用场景

1 .getSnapshotBeforeUpdate,getDervedStateFromError,componentDidCatch这几个生命周期还没有对应的学法
2 .如果组件必须要需要这几个生命周期函数,可以使用class形式

从Class迁徙到Hook

1 .constructor:函数组件不需要构造函数,你可以通过调用useState来初始化state.
2 .getDerivedStateFromProps

1 .改成在渲染时安排一次更新

3 .shouldComponentUpdate:

1 .memo

4 .render:这是函数本身组件
5 .componentDidMount,componentDidUpdate,compoenntWillUnmount:

1 .useEffect hook

6 .getSnapshotBeforeUpdate,componentDidiCatch,getDerivedStateFromError

1 .目前没有对应的hook写法,需要下一个版本

进行数据获取

实例变量

1 .useRef 类似一个class的实例属性。ref对象的current属性可以变化,而且可以容纳任意值的通用容器

function Timer() {
  const intervalRef = useRef();

  useEffect(() => {
    const id = setInterval(() => {
      // ...
    });
    intervalRef.current = id;
    return () => {
      clearInterval(intervalRef.current);
    };
  });
function handleCancelClick() {
    clearInterval(intervalRef.current);
  }
//可以在别的函数里面手动关闭
}

单个还是多个state变量

1 .把state切分成多个state变量,每个变量包含的不同值

获取上一轮的props或者state

看到的是旧的state值

1 .在先点击handleAlertClick 这个函数,这个等待执行的时候,再次改变state的值,此时如果有依赖的话,是不会显示最新的值,而是直接使用原来的
2 .组件内部的任何函数,包括时间处理函数和effect,都是被从他们创建的那次渲染中被绑定数据的
3 .如果想要从异步回调中读取最新的值,可以创建一个ref来保存值,并读取他

import React,{useState} from 'react'

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

    function handleAlertClick(){
        setTimeout(()=>{
            console.log('count',count)
        },3000)
    }
    // 第一次渲染这个函数的时候其实已经计算好了,这里会显示0

    return (
        <div>
            <p>you click {count}times</p>
            <button onClick={()=>setCount(count+1)}> click me</button>
            <button onClick={handleAlertClick}>Show comsole</button>
        </div>
    )
}export default Example

//变成ref就能获取到最新的值,即使在获取的阶段进行更新
import React,{useState,useRef} from 'react'

function Example(){
    const [count,setCount]=useState(0)
    const ref=useRef(0)
    ref.current=0

    function handleAlertClick(){
        setTimeout(()=>{
            console.log('count',ref.current)
        },3000)
    }
    // 第一次渲染这个函数的时候其实已经计算好了,这里会显示0

    return (
        <div>
            <p>you click {count}times</p>
            <button onClick={()=>ref.current=10}> click me</button>
            <button onClick={handleAlertClick}>Show comsole</button>
        </div>
    )
}export default Example

Class 组件和function组件的渲染效率

1 .函数组件每次渲染创建大量的闭包,传统的class组件的render非常简洁
2 .在现代浏览器中,只有特别极端的场景下才会有明显的差别
3 .hook避免了class需要的额外开销,比如创建类实例以及构造函数中绑定事件处理器的成本
4 .符合语言习惯的代码在使用hook时不需要很深的组件嵌套。
5 .同样的功能,类组件和函数组件的效率是不相上下的,但是函数组件是未来趋势
6 .

引用类型的数据不能感知到变化

function useTest(){
    const [Arr,setArr]=useState([])
    const [count,setCount]=useState(0)
    useEffect(()=>{
        function handleClick(){
            console.log('click')
            const data=new Date()
            const arr=Arr
            arr.push(data)           
            setArr(arr)
            setCount(count+1)
            console.log(arr)
        }
        document.addEventListener("click",handleClick)
    },[])
    // 如果这里不加[],别的hook执行,触发render,那么这个也会每次都执行,那么这里就也会每次render都执行,一直往数组里面push东西,所以下一次点击的时候数组里面会保存很多

    useEffect(()=>{
        console.log('change')
        // 这个数组的检测其实是不能触发到的
        // 引用类型的值其实这里是不能操作的

    },[Arr])
}

只能再最顶层使用hook

1 .不能再循环,条件,或者嵌套函数里面调用。只有这样才能在hook每一次调用的时候按照相同的顺序被调用。
2 .保证react能够在多次的useState,useEffect调用之间保持hook状态的正确
3 .只能在react函数种调用hook,不能再普通js函数里面调用hook
4 .只要hook的调用顺序在多次渲染之间保持一致,react就能正确的将内部state和对应的Hook进行关联

useEffect模拟comonentDidMount生命周期

1 .可以使用useEffect(fn, []),但是他们并不完全相等
2 .useEffect会捕获props,state,你拿到的值仅仅是初始的,执行这个函数的时候对应的值
3 .如果想要拿到最新的值,需要使用ref
4 .试图找到effect和生命周期一致的表达更容易使你混淆,需要做的还是要跳出生命周期函数
5 .

上一篇下一篇

猜你喜欢

热点阅读