这里文章说的都是hooksreact

那什么是hooks

故名思义 Hooks 译为钩子,Hooks 就是在函数组件内,负责钩进内部性能的函数。

(说了又如同没说)

有什么爽的

  • 函数组件原地飞升
  • 不必管this了
  • 生命周期也不必记那么多了

开始完结的生命周期能够写在一起,代码更丑陋了

useEffect(()=>{  console.log('开波')  return ()=>{    console.log('完结')  }},[])// ps.空数组就是只进入一次

props的值的变动,xx值的变动都能放在一起监听

useEffect(()=>{  console.log('无论是数组还是对象,数据多深都能进(起初才发现也不是多深都能啦),这不比vue的watch爽?')  // 那么useEffect是怎么监听数据变动的呢  // 它和useLayoutEffect又有什么区别呢  // 这要从hooks的根底概念链表说起,请往下看},[props.a,b])

通过看useEffect的源码,咱们不难发现

// 通过看源码咱们得悉 for (let i = 0; i < prevDeps.length && i < nextDeps.length; i++) {    if (is(nextDeps[i], prevDeps[i])) {      continue;    }    return false;  }// 咱们晓得它的比照办法是// 其中外面的is是这个import is from 'shared/objectIs';function is(x: any, y: any) {  return (    (x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y) // eslint-disable-line no-self-compare  );}const objectIs: (x: any, y: any) => boolean =  typeof Object.is === 'function' ? Object.is : is;export default objectIs;

所以其实它就是用Object.is做比拟

有须要做深比拟的能够用ahooksuseDeepCompareEffect,用法与 useEffect 统一,但 deps 通过 lodash 的isEqual进行深比拟。
  • 代码复用更高

吐槽一下

闭包陷阱

import {useEffect, useState} from 'react'export default function App() {  const [count, setCount] = useState(0)  useEffect(()=>{    setInterval(() => {      setCount(count + 1)    }, 1000);  }, [])  return (       <p>count={count}</p>  );}

大家可能会始终期待着数字的变动,但它就偏不,始终放弃着1

事件为什么会倒退成这样,那就要从底层的渲染开始说起

首次渲染->执行APP->usestate设置count为初始0->1秒后state扭转->视图更新->依照fiber链表执行hooks->useEffect deps 不变->而后1秒后的count始终都是0+1

解决办法:

// 有仔细的网友可能会发现,网上其余中央可能会倡议在useEffect的deps上加上countuseEffect(()=>{  setInterval(() => {    setCount(count + 1)  }, 1000);}, [count])// 这样的确能拿到最新的count// ❌然而这里喔不倡议这样写// 因为你想想,每次count的更新它都会从新进去建一个新的定时器// 当前画面就会很鬼畜

倡议版本办法

useEffect(()=>{  setInterval(() => {    setCount(res=>(res+1))  }, 1000);}, [])// setCount自身能够传办法,原本就是最新的值

高级版本ref大法

//简略来说就是利用useRef返回的是同一个对象,指向同一片内存let ref_ = useRef(1)ref_.current++useEffect(()=>{  setInterval(()=>{  console.log(ref.current) // 3  }, 1000)})

不能用判断或者随机函数

举个

if (Math.random() > 0.5) {  useState('first')} let showSex = trueif(showSex){    const [ sex, setSex ] = useState('男');    showSex = false;}

以上的行为都是打咩的

起因是hooks的数据管理是用链表治理的,所以数据不能一时有一时没

举个不太失当的例子,就像

  • 数组[0]代表useState('A')
  • 数组[1]代表useState('B)
  • 当初你忽然把'A'删掉了,那就变成数组[0]代表useState('B')了
  • 那么你就不是你了,他也不是他了

useCallBack 还是 useMemo

仅仅 依赖数据 发生变化, 才会从新计算结果,说是为了性能优化,起到缓存的作用,

这里说一个面试常问的useCallBackuseMemo 有什么区别?

网上各种解析简明扼要的,一句话其实就是

useCallback 缓存钩子函数,useMemo 缓存返回值(计算结果)[当然useMemo也能够传入函数]。

这个时候,有好奇宝贝就会问了,那用这个会多那么多代码量,有什么用呢

答案是:性能优化,这里就要波及到更深层的react的渲染原理了,"比拟更新!!",react每次渲染的时候,它都把值和函数从新计算渲染,这里就会耗费点内存了,用上那2玩意,其实就是通知react,咱们没有变动,帮我存起来,不必再比拟了

那么有些姓杠的小朋友,这时候就不耐烦了,站起来问道:为什么react不帮咱们主动做这些优化呢,我就想静静地写代码,为什么还要思考该不该包个useCallBack

问得好,这里顺便@一下官网团队,心愿相干单位能亲密关注这个问题

还会有些害羞的小朋友会嘀咕着,为什么class组件的时候就不须要留神这些呢

集体鄙见:新旧版本的渲染办法其实差不多的,我感觉前端深入研究性能优化是没有前途的,框架或者浏览器,一次小小的版本更新,可能成果就远远胜过了你多少个日日夜夜的辛勤付出了。

总结

hooks需好,但要小心应用


<center>明天关注公众号,有小哥哥在线领导</center>

本文由博客一文多发平台 OpenWrite 公布!