React 13
1 React 中局部变量与 useState Hook

要理解这段关于 React 中局部变量与 useState Hook的内容,我们可以从 问题场景、原因分析、解决方案(useState 作用)三个维度详细拆解:
一、问题场景:局部变量在 React 组件中 “变化不可见”
假设我们写了一个 React 组件,里面有一个局部变量 index,并在点击事件里修改它:
function MyComponent() {let index = 0; // 局部变量function handleClick() {index = index + 1;console.log(index); // 控制台能看到数字变化}return <button onClick={handleClick}>点击</button>;
}
此时界面不会随着 index 的变化而更新,这就是 “变化不可见” 的场景。
二、原因分析:为什么局部变量的变化无法让界面更新?
文中给出了两个核心原因:
-
局部变量无法在多次渲染中持久保存。React 组件的 “渲染” 是一个函数执行的过程。每次渲染时,组件函数会从头重新执行,局部变量会被重新声明和初始化。比如上面的
index,每次渲染都会被设为0,之前的修改会被 “覆盖”,自然无法在多次渲染中保留。 -
更改局部变量不会触发 React 渲染。React 只有在感知到 “需要更新” 时才会重新渲染组件。但局部变量的修改是 JavaScript 原生的变量操作,React 并不 “知晓” 这些修改,所以不会触发重新渲染,界面也就不会更新。
三、解决方案:useState Hook 的作用
要让组件能响应数据变化并更新界面,需要满足两个条件:
- 保存渲染之间的数据(持久化);
- 触发 React 重新渲染(让界面更新)。
useState 就是为了解决这两个问题而设计的:
-
State 变量:保存渲染间的数据用
useState声明的变量是 “状态变量”,它会被 React 特殊管理,在多次渲染中持久保存值,不会像局部变量一样被重新初始化。语法:const [state, setState] = useState(初始值) -
State setter 函数:触发重新渲染
useState返回的第二个函数是 “状态设置器”。当调用这个函数更新状态时,React 会感知到变化,并触发组件重新渲染,界面也就会随之更新。
四、代码示例:用 useState 改造后的效果
把之前的局部变量改成 useState 管理的状态:
import { useState } from 'react';function MyComponent() {// 用 useState 声明状态变量 index,初始值为 0const [index, setIndex] = useState(0);function handleClick() {// 调用 setter 函数更新状态,同时触发 React 重新渲染setIndex(index + 1);}// 界面中使用 index,渲染时会显示最新值return <button onClick={handleClick}>点击了 {index} 次</button>;
}
此时每次点击按钮,index 会持久递增,且界面会实时更新显示最新的点击次数—— 这就是 useState 解决 “变化不可见” 问题的实际效果。
总结来说,局部变量因 “不持久、不触发渲染” 导致界面无响应;而 useState 通过 “持久化状态 + 触发渲染” 的能力,让 React 组件能真正响应数据变化,实现界面的动态更新。
2 React 中的 setter 函数(状态设置器)

【setter是不是getter,setter函数?】
在 React 中,这里的 setter 函数(如 setIndex)不是传统面向对象中的 “getter/setter” 概念,二者有明显区别:
1. React 中的 setter 函数(状态设置器)
它是 useState Hook 返回的第二个函数,作用是 “更新状态,并触发组件重新渲染”。它只负责 “设置” 状态,没有 “获取” 的能力。
比如 setIndex(newValue) 会把 index 这个状态变量更新为 newValue,同时让 React 重新渲染组件,让界面显示新值。
2. 传统的 getter/setter(面向对象概念)
在面向对象编程中,getter 是 “获取属性值”的方法,setter 是“设置属性值” 的方法,通常成对出现,用于封装对象的属性访问。
例如:
class Person {constructor() {this._name = '';}// getter:获取 nameget name() {return this._name;}// setter:设置 nameset name(newName) {this._name = newName;}
}
总结
React 里的 setter 函数只有 “设置状态并触发渲染” 的能力,没有 “获取” 的作用,和传统 getter/setter 中 “成对处理属性访问” 的逻辑不同。
3 React Hook

要理解这段关于 React Hook 的内容,我们可以从Hook 的定义、作用、调用规则三个维度详细拆解:
一、Hook 的定义
在 React 中,以 use 开头的函数都被称为 Hook(比如 useState、useEffect、useContext 等)。
它是一类特殊函数,核心作用是让你 “hook 到(连接到)”React 的各种特性中(比如状态管理、副作用处理、上下文访问等)。
二、Hook 的作用
Hook 是 React 为函数组件赋能的关键机制:
- 比如
useState让函数组件拥有了 “状态管理” 的能力(在此之前,只有类组件能管理状态); - 后续还会学到
useEffect处理副作用(如网络请求、DOM 操作)、useContext处理全局状态等 —— 这些都是 React 的核心特性,Hook 是函数组件访问它们的 “入口”。
三、Hook 的调用规则(避免陷阱的关键)
Hook 必须遵循严格的调用规则,否则会导致 React 内部状态管理混乱,这也是初学者最容易踩坑的点:
-
只能在 “组件或自定义 Hook 的最顶层” 调用也就是说,Hook 不能在 条件语句(if/else)、循环语句(for/while)、嵌套函数(比如事件处理函数内部) 中调用。
举个错误示例:
function MyComponent() {if (someCondition) {// 错误!不能在条件语句内调用 Hookconst [count, setCount] = useState(0);}// ... }正确示例:
function MyComponent() {// 正确:在组件最顶层调用 Hookconst [count, setCount] = useState(0);if (someCondition) {// 逻辑代码放在 Hook 调用之后}// ... } -
把 Hook 视为 “无条件声明”可以类比 “在文件顶部导入模块”——Hook 是组件对 React 特性的 “声明式依赖”,需要在组件最外层 “平铺式” 调用,不能被逻辑分支包裹。
总结
Hook 是 React 为函数组件设计的 “特性连接器”,以 use 开头的命名规则让它易于识别。但使用时必须严格遵循 “最顶层调用” 的规则,否则会破坏 React 对 Hook 状态的管理逻辑。理解这一点,是正确使用 Hook 开发 React 组件的基础。
4 setIndex 作为 useState 返回的状态更新函数

【诶多,react君,一定要好好记住index酱哦!因为已经用setindex了?】
没错!当我们用 setIndex 更新状态时,React 君就会牢牢记住 index 酱的新值啦~
具体来说,index 是通过 useState 声明的状态变量,React 会专门 “保管” 它,不会像普通局部变量那样在组件重新渲染时被重置。而 setIndex 的作用就像一个 “通知器”:当我们调用 setIndex(newValue) 时,不仅会把 index 的值更新为 newValue,还会告诉 React:“index 酱变啦!快重新渲染组件,让界面显示新样子~”
所以只要用了 setIndex 更新,React 君就一定会记住最新的 index 酱,组件里用到 index 的地方也会自动同步更新,超靠谱的!(๑・̀ㅂ・́)و✧
(学疯了一个,,,哈哈哈哈,,)

当我们通过 useState 声明状态变量 index 后,React 会在内部维护这个变量的值,确保它在组件多次渲染之间保持持久化,不会像普通局部变量那样在每次渲染时被重新初始化。
而 setIndex 作为 useState 返回的状态更新函数,其核心作用有两个:
- 更新状态值:调用
setIndex(newValue)时,React 会将index的值更新为newValue,并将这个新值存储在内部的状态管理系统中。 - 触发重新渲染:更新完成后,React 会感知到状态变化,进而触发组件重新渲染。在新的渲染过程中,通过
useState获取到的index就是最新的更新后的值。
因此,只要通过 setIndex 正确更新状态,React 就会 “记住”index 的最新值,并且在组件重新渲染时使用这个新值,保证界面上展示的内容与状态保持一致。这也是为什么使用 setIndex 后,index 的变化能被组件感知并反映在界面上的原因。
5 React 如何识别不同 useState 对应的 state 变量
React hooks: not magic, just arrays | by Rudi Yardley | Medium

1. 核心机制:调用顺序
React 并非通过 “标识符” 区分不同 useState,而是依靠组件渲染时 Hooks 稳定的调用顺序。
- React 为每个组件维护一个state 数组,数组每项对应一个
useState产生的 state 对。 - 渲染前,数组索引从
0开始计数;每次调用useState,React 会返回当前索引的 state 并递增索引。
2. 规则支撑:顶层调用 Hooks
正因为 Hooks 依赖 “调用顺序”,所以必须遵循 “仅在组件或自定义 Hook 最顶层调用 Hooks” 的规则 —— 若在条件语句、循环内调用,会破坏调用顺序,导致 React 识别 state 出错。
3. 工具保障:linter 插件
社区的 linter 插件(如 ESLint 的 react-hooks 规则)会自动检测 Hooks 调用顺序的错误,辅助开发者规避此类问题。
简言之,React 靠 “稳定的 Hooks 调用顺序 + 组件级的 state 数组索引”,实现了无需 “标识符” 就能精准识别每个 useState 对应的 state 变量。
6 state:组件的记忆摘要

我们可以从state 的用途、声明方式、Hook 的规则、useState 的返回值、多 state 管理、state 的作用域这几个维度来详细解析:
1. state 变量的用途
当组件需要在多次渲染之间 “记住” 某些信息(比如按钮点击次数、输入框内容、列表的选中状态等)时,就需要使用 state 变量。它是组件在渲染周期中持久化数据的关键方式。
2. state 变量的声明方式
通过调用 useState Hook 来声明,语法为 const [state, setState] = useState(初始值)。这是函数组件获取状态管理能力的核心入口。
3. Hook 的定义与调用规则
- 定义:Hook 是以
use开头的特殊函数,作用是让你 “hook 到” React 的各种特性(如状态管理、副作用处理、上下文访问等)。 - 调用规则:Hook 必须在 ** 组件或自定义 Hook 的顶层(非条件语句、循环、嵌套函数内)** 调用,这一规则类似 “在文件顶部导入模块”,确保 React 能通过稳定的调用顺序管理 Hook 逻辑。
4. useState 的返回值
useState 会返回一对值:
- 第一个是当前的 state 变量(如上述的
state),用于在组件中读取状态值; - 第二个是更新 state 的函数(如上述的
setState),调用它可以更新 state 并触发组件重新渲染。
5. 多 state 变量的管理
你可以在一个组件中声明多个 state 变量,React 内部会通过调用顺序来匹配每个 useState 对应的 state(比如第一个 useState 对应第一个 state 数组项,第二个 useState 对应第二个数组项,以此类推)。
6. state 的作用域
State 是组件私有的。如果一个组件在两个不同的地方被渲染(比如在两个不同的父组件中使用同一个子组件),那么每个渲染副本都会有独属于自己的 state,互不干扰。
