React Hooks 的理解

572 阅读4分钟

前段时间看了大佬卡颂理解 Hooks 的视频 👉 9分钟掌握React Hooks正确认知,很精彩。正好接触 React 也有四五个月的时间了,做项目时断断续续过了一下 React Hooks 的官方文档,视频中有的句子感觉读起来不顺口,所以整理了一下,做个笔记吧~

理解 Hooks 的方式

在学习新的技术时,类比是常用的方法,用之前理解的概念去类比新的知识点,可以很快理解新的内容。所以当函数组件引入了 Hooks 的概念后,往往都是去类比 Class components。即使官方文档也直接说 useEffect similar to componentDidMount and componentDidUpdate 😂

要用生命周期去理解 Hooks 是不合适的,Hooks 提供状态给函数组件,而函数组件本来就没有生命周期的说法。个人觉得用生命周期去理解useEffect,在遇到状态变化组件不更新的时候,会带来一些心智负担😅

视频介绍了一个很通俗易懂的方式去理解 Hooks:自变量和因变量。

y=2x+1y = 2x + 1

学过初中的数学的都知道对于上面的二元一次方程,xx 被称作自变量,yy 被称作因变量。

下面来看看如何理解。

useState

定义了一个函数组件:

import { useState } from 'react'

export default function App() {
  const [x, setX] = useState(0)
  
  const changeX = () => setX(x + 1)
  
  return (
  	<ul onClick={changeX}>
    	<li>x 是 {x}</li>
    </ul>
  )
}

触发点击事件会更新 xx 更新,视图也会更新。

加上因变量 y

import { useState } from 'react'

export default function App() {
  const [x, setX] = useState(0)
  
+ const y = 2 * x + 1
  const changeX = () => setX(x + 1)
  
  return (
  	<ul onClick={changeX}>
    	<li>x 是 {x}</li>
+     <li>y 是 {y}</li>
    </ul>
  )
}

自变量 x 的改变,让因变量 y 改变,y 对应的视图也会改变

useMemo 和 useCallback

使用 useMemouseCallback 需要缓存的因变量

  • useMemo 缓存因变量( 这里是 y ),需要显示的指定该因变量依赖的自变量
  • useCallback缓存函数类型的因变量( 这里是 changeX ),同样需要显示的指定因变量的依赖的自变量
+ import { useState, useMemo, useCallback } from 'react'

export default function App() {
  const [x, setX] = useState(0)
  
- const y = 2 * x + 1
+ const y = useMemo(() => 2 * x + 1, [x])

- const changeX = () => setX(x + 1)
+ const changeX = useCallback(() => setX(x + 1), [x])
  
  return (
  	<ul onClick={changeX}>
    	<li>x 是 {x}</li>
      <li>y 是 {y}</li>
    </ul>
  )
}

区别是,如果 x不变始终读取的是缓存的值。如果不使用,每次执行函数组件会创建新的y,changeX

useEffect

使用 useEffect 处理副作用,往往是因为某个自变量引起的。

那么什么是副作用?可以理解为对环境产生的影响就是产生了副作用

(注意:对环境的影响可以是好的也可以是不好的。所以副作用不一定是不好的)

比如 js 运行的环境是浏览器,浏览器提供了 DOM,那么对 DOM 的操作就在对环境产生影响。

继续上面的代码

+ import { useState, useEffect } from 'react'

export default function App() {
  const [x, setX] = useState(0)
  
  const y = 2 * x + 1
  const changeX = () => setX(x + 1)
  
+ useeffect(() => {
+	  document.title = x;
+ }, [x])
  
  return (
  	<ul onClick={changeX}>
    	<li>x 是 {x}</li>
      <li>y 是 {y}</li>
    </ul>
  )
}

useStste 定义的自变量 xx 变化不仅可以触发视图变化,还能触发副作用。

小结:

  • useState 定义自变量

  • useMemo useCallback 定义没有副作用的因变量

  • useEffect 定义有副作用的因变量

那么还剩:

  • useReducer 是把多个 state 合并为一个,本质上是自变量。

  • useContext 解决跨组件层级传递自变量

useRef

在自变量和视图之间做一些事情,往往需要借助某个变量(这个变量和视图没有直接关系),也可以放在自变量和因变量有关系的地方。

(这里我还需要多多想想有什么相关的例子)

示意图

image.png

感受

不要用组件生命周期去理解 Hooks,尤其对于之前用 Vue 的我来说,一开始会把生命周期当作万金油,用 React 的 Class componets 的时候,亲切到不行,心想明明都一样嘛……虽然之前项目也有用过 Vue3 的 Composition API,但当时的体会是都写在 setup 里面好乱啊。。。慢慢了解了一些编程范式后,体会到可能 Vue3 的正确使用方式也是 Hooks。