渲染是一次计算
组件本质上是返回 JSX 的函数,每次渲染都会重新执行一遍函数体。任何在函数体内直接声明的变量都会随渲染重建,这不是缺陷,而是模型的一部分。
因此派生数据应当直接从 props 与 state 算出来,而不是再塞进一个 useState 里同步两次。
Component Notes
从组件与状态出发,把渲染模型、Hooks 规则与工程化实践讲成一条能走通的路。
这份教程写给已经能写 HTML 与基础 JavaScript、但面对 JSX 和 Hooks 时容易迷路的人。它不追求把 API 一次列全,而是先讲清楚 React 到底在做什么:把界面描述成状态的函数,再让最小的更新落到真正的 DOM 上。
读完之后,你应当能够独立写出一个带数据请求、表单状态与条件渲染的页面组件,并且知道为什么某些写法会导致多余渲染。
组件本质上是返回 JSX 的函数,每次渲染都会重新执行一遍函数体。任何在函数体内直接声明的变量都会随渲染重建,这不是缺陷,而是模型的一部分。
因此派生数据应当直接从 props 与 state 算出来,而不是再塞进一个 useState 里同步两次。
React 用引用比较判断是否需要重绘。直接改对象属性或数组 push,引用没变,界面就不会动。
正确做法是展开出新对象:setForm(prev => ({...prev, name}))。函数式更新还能避免闭包拿到过期的旧值。
useEffect 描述的是「与外部系统同步」,不是「挂载后做某事」。依赖数组决定的是同步的粒度,漏掉依赖往往意味着订阅与取消订阅不配平。
能在渲染期算出来的东西不要放进 Effect;事件触发才做的事应该写在事件处理函数里。
列表渲染的重点不在遍历语法,而在 key 是否稳定。用数组下标做 key,在增删排序时会把旧组件的内部状态错配到另一条数据上。
优先使用数据自带的唯一标识;当数据确实没有 id 时,在进入列表前生成一次并保存。
import { useState, useEffect } from 'react'; export default function Counter({ step = 1 }) { const [count, setCount] = useState(0); useEffect(() => { document.title = `当前计数:${count}`; }, [count]); return ( <button onClick={() => setCount(c => c + step)}> 计数 {count} </button> ); }
AbortController 在清理函数里取消,避免卸载后写入状态。本页长期整理 React 学习笔记与实践示例,内容按主题持续校订。如需核对站点归属,可通过页面底部备案信息确认主体。