React Hooks是 React 16.8 推出的新的理念,那 Hooks 是什么意思,为什么叫 Hooks,很多系统都有 Hooks这个概念,就是 Hook 到现有的系统中,比如在调用某个函数之前,运行一下这个自定义函数,也叫钩子函数。知道了 Hooks 的意思,那 React 为啥要引入 Hooks, 有什么好处呢?
在 Hooks 出现之前,函数式组件是无状态的,如果你的组件中要保持状态,就只能用类组件。类组件写起来要复杂一些,要处理 this,要写 constructor 等等。那么Hooks 是怎么运行的呢,以及 Hooks 是怎么记录状态的?
首先,当函数组件第一次执行时,React 为其创建一个节点,React 叫 Fiber Node。与此同时,React 创建了一个数组来管理钩子函数,数组保存了钩子函数以及钩子函数的状态。在函数组件中调用的每个钩子(如 useState 或 useEffect)都在这个钩子列表中进行保存。列表维护每个钩子的顺序和状态,这样在每次渲染时可以正确按顺序执行。
当状态变化发生变更时(例如,通过 useState 返回的函数进行数据更新),此时,React 标记组件需要更新。这触发了组件的重新渲染,在渲染期间,函数组件再次被调用。React 使用与组件的Fiber Node关联的钩子列表来维持连续性,这意味着通过钩子如 useState 查到的状态值是从上次渲染存储的更新值,而不是重新初始化。React 遍历钩子列表,根据组件中的逻辑和钩子的依赖进行组件状态的更新。
我认为 Hooks 最大的优点就是组件的状态解耦了,不用关心状态怎么存的,都是和组件节点关联的,开发中不需要关心,可以方便进行扩展,例如新加的功能需要访问状态直接用 useState 就可以了,直接可以访问组件的状态。
下面看两个最常用的Hooks 函数:
useState
useState 好理解,一个状态加一个更新状态的函数,需要更新就调用返回的函数。
import { useState } from "react";
const state = useState();
export default function ColorPicker() {
const colorState = useState()
console.log('Color State : ', colorState)
return (
<main>
<h1>React Color Picker</h1>
</main>
)
}
useEffect
useEffect是组件渲染完成之后才会执行的,和 didMount 生命周期函数类似。这里需要理解一下的就是这个副作用,这是函数中一个概念,就是函数组件在渲染的时候没有副作用,运行多少次结果都是一样的,副作用的逻辑都在 useEffect,如果没有依赖(第二个参数),useEffect 只会运行一次。
import { useEffect } from "react";
export default function Todo() {
function fetchTodos(){
fetch('https://jsonplaceholder.typicode.com/todos')
.then(response => response.json())
.then(json => console.log(json))
}
useEffect(fetchTodos, []);
return (
<div>
<h1>Todo App</h1>
</div>
)
}