React 基础学习笔记
适合目标:系统掌握 React 基础开发能力,并能回答常见面试题。
学习定位:这一份偏“会用、会答、会优化”,适合先建立 React 使用层的完整知识体系。
学习原则:先理解 React 的思维方式,再记 API;先会写组件,再讲优化;先能解释业务场景,再背面试答案。
目录
- 学习总览
- React 的核心思维
- JSX 与组件基础
- Props、State 与渲染
- 事件、表单与列表渲染
- 生命周期思维与函数组件时代
- Hooks 全家桶
- 组件通信
- 状态管理选型
- React 18 高频知识点
- 性能优化手段
- 高频面试题
- 6 小时学习规划
- 一页速记总结
- 背诵口诀
1. 学习总览
1.1 React 到底在解决什么问题
React 不是一个“页面模板语言”,它本质上是在帮我们解决这几个问题:
- 界面如何拆成可复用组件
- 状态变化后,界面如何自动更新
- 多个组件之间,数据如何流动
- 当页面变复杂时,如何保持可维护性
你可以把 React 理解成:
UI = f(state)
意思是:
- 界面是状态的映射
- 状态变了,界面就重新计算
- 我们重点维护“状态”和“组件结构”,DOM 更新交给 React
1.2 学 React 要先建立的三条主线
主线 1:组件化
把一个页面拆成多个独立的、可组合的组件。
主线 2:数据驱动视图
不是手动改 DOM,而是修改状态,让 React 帮你更新视图。
主线 3:单向数据流
父组件通过 props 向下传递数据,状态提升和回调函数负责交互。
1.3 React 学习顺序
建议按这个顺序建立体系:
- JSX 和组件
- props 和 state
- 事件、列表、条件渲染
- Hooks
- 组件通信
- React 18 特性
- 性能优化
- 状态管理
2. React 的核心思维
2.1 声明式 UI
React 是声明式的,不是命令式的。
命令式思维
你需要自己一步一步操作 DOM:
- 找到节点
- 修改文本
- 添加 class
- 控制显示隐藏
声明式思维
你只需要表达:
当前状态下,界面应该长什么样
React 会根据新旧状态,帮你把 DOM 更新到正确结果。
示例:
function Counter() {
const [count, setCount] = React.useState(0);
return (
<div>
<p>当前计数:{count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
</div>
);
}
2.2 组件化思维
React 项目里,一个页面通常会拆成:
- 页面组件
- 业务组件
- 通用组件
- 布局组件
- 纯展示组件
拆分标准可以记成三点:
- 是否可复用
- 是否职责独立
- 是否会单独变化
2.3 单向数据流
React 里最重要的思想之一就是:
数据通常从父到子流动
父组件:
- 持有状态
- 通过
props传给子组件 - 通过回调让子组件通知父组件
示例:
function Parent() {
const [count, setCount] = React.useState(0);
return <Child count={count} onAdd={() => setCount((c) => c + 1)} />;
}
function Child({ count, onAdd }) {
return <button onClick={onAdd}>当前值:{count}</button>;
}
2.4 React 中最重要的两个词
Render
根据当前状态计算出应该渲染什么 UI。
Re-render
状态变了,组件重新执行,生成新的虚拟结构。
注意:
- 重新渲染不等于 DOM 一定重建
- React 会比较新旧结果,再决定最小化更新
2.5 记忆口诀
React 不直接教你改页面,而是让你描述状态下的页面。
3. JSX 与组件基础
3.1 JSX 是什么
JSX 是 JavaScript 的语法扩展,看起来像 HTML,但本质不是字符串模板,而是会被编译成 React 元素对象。
const element = <h1>Hello React</h1>;
会被转换成类似:
const element = React.createElement("h1", null, "Hello React");
3.2 JSX 的核心规则
- 必须有一个根节点
- 标签必须闭合
- 使用驼峰命名属性,如
className、onClick - 在 JSX 中插入 JS 表达式要用
{}包裹
示例:
function App() {
const name = "Tom";
return <div className="app">Hello, {name}</div>;
}
3.3 JSX 里能放什么
{} 中可以放:
- 变量
- 表达式
- 三元表达式
- 函数调用结果
- 数组映射结果
不能直接放:
if语句for语句- 普通对象本身
3.4 组件是什么
组件就是返回 UI 描述的函数。
function Welcome() {
return <h1>Hello</h1>;
}
组件名必须大写开头,否则会被当成原生标签。
3.5 组件的分类
函数组件
现代 React 开发主流。
function Button() {
return <button>按钮</button>;
}
类组件
现在仍需理解,但日常新项目基本以函数组件为主。
class Button extends React.Component {
render() {
return <button>按钮</button>;
}
}
3.6 props 是什么
props 是组件的输入参数,用于父组件向子组件传值。
function UserCard(props) {
return <div>{props.name}</div>;
}
更常见写法:
function UserCard({ name, age }) {
return (
<div>
<p>{name}</p>
<p>{age}</p>
</div>
);
}
3.7 children 是什么
children 是组件标签内部的内容。
function Card({ children }) {
return <div className="card">{children}</div>;
}
function App() {
return <Card><h2>标题</h2></Card>;
}
3.8 条件渲染
常见方式:
- 三元表达式
&&- 提前
return
function UserInfo({ isLogin }) {
if (!isLogin) return <p>请登录</p>;
return <p>欢迎回来</p>;
}
3.9 列表渲染
React 中渲染列表通常用 map。
function TodoList({ list }) {
return (
<ul>
{list.map((item) => (
<li key={item.id}>{item.text}</li>
))}
</ul>
);
}
3.10 key 为什么重要
key 是 React 在同层节点中识别元素身份的重要标记。
作用:
- 帮助 React 复用节点
- 减少不必要更新
- 保持列表项状态稳定
不要乱用 index 的场景:
- 列表有插入、删除、排序
- 列表项内部有本地状态
3.11 JSX 与组件记忆口诀
JSX 是语法糖,组件是函数,props 是输入,children 是插槽。
4. Props、State 与渲染
4.1 state 是什么
state 是组件内部可变化的数据。
React 中状态变化会触发重新渲染。
function Counter() {
const [count, setCount] = React.useState(0);
return (
<div>
<span>{count}</span>
<button onClick={() => setCount(count + 1)}>+1</button>
</div>
);
}
4.2 props 和 state 的区别
| 对比项 | props | state |
|---|---|---|
| 来源 | 父组件传入 | 组件内部维护 |
| 是否可直接修改 | 不应该 | 通过更新函数修改 |
| 作用 | 组件输入 | 组件自身状态 |
4.3 React 中一次状态更新发生了什么
可以先这样理解:
- 调用
setState/setCount - React 记录这次更新
- 组件重新执行
- 生成新的虚拟 UI
- React 比较新旧结果
- 只更新有变化的部分
4.4 为什么 state 更新后不是立刻拿到新值
这类题很高频。
示例:
function App() {
const [count, setCount] = React.useState(0);
const handleClick = () => {
setCount(count + 1);
console.log(count); // 旧值
};
return <button onClick={handleClick}>点击</button>;
}
原因:
- React 状态更新是异步调度的
- 当前函数执行时,拿到的是本次渲染闭包中的旧值
- 重新渲染后,组件才会拿到新状态
4.5 为什么连续 setCount(count + 1) 可能只加 1
setCount(count + 1);
setCount(count + 1);
因为两次都基于同一个旧 count。
正确写法:
setCount((c) => c + 1);
setCount((c) => c + 1);
函数式更新适合:
- 新状态依赖旧状态
- 同一轮里可能连续触发多次更新
4.6 不可变更新为什么重要
React 依赖引用变化判断很多更新场景,因此更新对象和数组时不要直接修改原数据。
错误写法:
user.name = "Jack";
setUser(user);
推荐写法:
setUser((prev) => ({ ...prev, name: "Jack" }));
4.7 派生状态要谨慎
很多初学者喜欢把“可由现有状态计算出来的值”也放进 state。
例如:
const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const fullName = `${firstName} ${lastName}`;
这里 fullName 没必要单独再放一个 state。
原则:
能算出来的,就不要重复存。
4.8 记忆口诀
props 是输入,state 是内部可变数据,更新状态要用新引用。
5. 事件、表单与列表渲染
5.1 React 事件是什么
React 事件写法和原生事件类似,但使用驼峰命名:
function App() {
const handleClick = () => {
console.log("clicked");
};
return <button onClick={handleClick}>点击</button>;
}
5.2 事件处理的常见写法
写法 1:直接传函数
<button onClick={handleClick}>点击</button>
写法 2:内联箭头函数
<button onClick={() => handleDelete(id)}>删除</button>
5.3 不要在渲染时直接执行函数
错误写法:
<button onClick={handleClick()}>点击</button>
这会在渲染阶段立刻执行。
5.4 受控组件
表单值由 React state 控制,就是受控组件。
function Form() {
const [value, setValue] = React.useState("");
return (
<input
value={value}
onChange={(e) => setValue(e.target.value)}
/>
);
}
优点:
- 数据源统一
- 方便校验
- 方便联动
5.5 非受控组件
表单值主要由 DOM 自己保存,通过 ref 获取,就是非受控组件。
function Form() {
const inputRef = React.useRef(null);
const handleSubmit = () => {
console.log(inputRef.current.value);
};
return (
<>
<input ref={inputRef} />
<button onClick={handleSubmit}>提交</button>
</>
);
}
5.6 受控和非受控怎么选
大部分业务表单优先受控组件,因为:
- 更符合 React 数据流
- 更容易做校验和联动
- 更容易和表单库配合
5.7 列表渲染常见坑
坑 1:用 index 作为 key
如果列表顺序变化,可能导致:
- 节点错误复用
- 输入框状态错位
- 动画错乱
坑 2:在 render 中做太重的计算
如果每次渲染都对大列表做复杂计算,会影响性能。
可以考虑:
- 预处理数据
useMemo- 虚拟列表
5.8 记忆口诀
表单优先受控,列表重视 key,事件传函数别提前执行。
6. 生命周期思维与函数组件时代
6.1 类组件生命周期先建立理解
虽然现代 React 主流是 Hooks,但面试中依然常把 Hooks 和生命周期对比着问。
类组件常见生命周期:
- 挂载:
constructor、render、componentDidMount - 更新:
render、componentDidUpdate - 卸载:
componentWillUnmount
6.2 函数组件没有传统生命周期方法
函数组件不是没有生命周期,而是换了一种理解方式:
- 每次渲染都是一次新的函数执行
useEffect用来处理副作用和清理- 渲染结果由当前 props 和 state 决定
6.3 如何理解 useEffect 对应生命周期
可以粗略类比:
useEffect(() => {}, [])类似挂载后执行一次useEffect(() => {}, [dep])类似依赖变化后执行return () => {}类似卸载前清理
但要注意:
useEffect 不是对生命周期的一一翻译,它更准确地说是“渲染后同步外部系统”。`
6.4 React 中副作用是什么
副作用就是那些不属于“纯渲染计算”的事情,比如:
- 请求数据
- 订阅事件
- 操作 DOM
- 定时器
- 手动修改标题
6.5 StrictMode 下 effect 为什么执行两次
开发环境下,React 严格模式会帮助你发现副作用问题,因此某些逻辑会出现“额外调用”。
常见表现:
- effect 执行两次
- 初始化逻辑跑两次
这通常只发生在开发模式,不代表生产环境也会双执行。
6.6 记忆口诀
类组件记生命周期,函数组件记渲染 + effect + 清理。
7. Hooks 全家桶
Hooks 是 React 基础中的核心,也是面试重点。
7.1 Hooks 总规则
规则 1:只在函数组件或自定义 Hook 中调用
规则 2:只在顶层调用,不要在条件、循环、嵌套函数里调用
原因:
React 依赖 Hook 调用顺序来匹配内部状态。
7.2 useState
作用
给函数组件添加状态。
const [count, setCount] = React.useState(0);
关键点
- 初始值只在首次渲染使用
- 更新状态会触发重新渲染
- 更新是异步调度的
- 新状态依赖旧状态时用函数式更新
惰性初始化
const [count, setCount] = React.useState(() => {
return Number(localStorage.getItem("count") || 0);
});
适合初始化成本较高的场景。
常见面试题
为什么 useState 不能条件调用?
答:
因为 React 需要依赖固定调用顺序,把每次渲染中的 Hook 和对应状态槽位一一匹配。
7.3 useEffect
作用
处理副作用。
useEffect(() => {
document.title = `count: ${count}`;
}, [count]);
依赖数组怎么理解
依赖数组表示:
effect 使用了哪些会变化的外部值
三种常见写法
不传依赖数组
每次渲染后都执行。
useEffect(() => {
console.log("每次渲染后执行");
});
传空数组
只在挂载后执行一次。
useEffect(() => {
console.log("仅首次执行");
}, []);
传具体依赖
依赖变化后重新执行。
useEffect(() => {
console.log("count 变化后执行");
}, [count]);
清理函数
useEffect(() => {
const timer = setInterval(() => {
console.log("tick");
}, 1000);
return () => {
clearInterval(timer);
};
}, []);
清理场景:
- 定时器
- 事件监听
- 订阅
- 网络请求中断
useEffect 常见误区
误区 1:把它当生命周期翻译器
本质应该理解成:渲染后同步外部系统。
误区 2:依赖项不写全
这会产生闭包陈旧值问题。
误区 3:effect 里堆太多逻辑
建议按关注点拆分多个 effect。
7.4 useRef
作用 1:拿 DOM 节点
function App() {
const inputRef = React.useRef(null);
return <input ref={inputRef} />;
}
作用 2:保存不会触发重渲染的可变值
const timerRef = React.useRef(null);
useRef 和 useState 的区别
| 对比项 | useRef | useState |
|---|---|---|
| 值变化是否触发渲染 | 不会 | 会 |
| 常见用途 | DOM、缓存实例、定时器 ID | 驱动界面更新的数据 |
7.5 useMemo
作用
缓存计算结果,避免重复执行昂贵计算。
const total = useMemo(() => {
return list.reduce((sum, item) => sum + item.price, 0);
}, [list]);
适合场景
- 计算量大
- 结果复用明显
- 依赖变化相对少
注意:
不要为了“看起来高级”到处加 useMemo。
7.6 useCallback
作用
缓存函数引用。
const handleClick = useCallback(() => {
console.log("click");
}, []);
什么时候有意义
- 函数传给被
React.memo包裹的子组件 - 作为某些 Hook 依赖,且你需要稳定引用
useMemo 和 useCallback 区别
useMemo缓存值useCallback缓存函数
可以简单记成:
useMemo(fn, deps) => 缓存 fn 的返回值
useCallback(fn, deps) => 缓存 fn 本身
7.7 useContext
作用
跨层级传值,避免一层层透传 props。
const ThemeContext = React.createContext("light");
function App() {
return (
<ThemeContext.Provider value="dark">
<Page />
</ThemeContext.Provider>
);
}
function Page() {
const theme = React.useContext(ThemeContext);
return <div>{theme}</div>;
}
适合场景
- 主题
- 用户信息
- 国际化
- 小中型共享状态
注意点
Context 不是万能状态管理。
如果 value 频繁变化且范围很大,可能导致不必要重渲染。
7.8 useReducer
作用
适合较复杂、规则明确的状态更新逻辑。
function reducer(state, action) {
switch (action.type) {
case "increment":
return { count: state.count + 1 };
case "decrement":
return { count: state.count - 1 };
default:
return state;
}
}
function Counter() {
const [state, dispatch] = React.useReducer(reducer, { count: 0 });
return (
<>
<p>{state.count}</p>
<button onClick={() => dispatch({ type: "increment" })}>+1</button>
</>
);
}
useReducer 适合什么场景
- 多个子状态相关联
- 状态流转复杂
- 希望更新逻辑集中管理
- 想和 Context 组合做轻量状态管理
7.9 自定义 Hook
自定义 Hook 本质上是复用状态逻辑,而不是复用 UI。
function useToggle(initial = false) {
const [value, setValue] = React.useState(initial);
const toggle = () => setValue((v) => !v);
return [value, toggle];
}
7.10 Hooks 总结口诀
useState 管状态,useEffect 管副作用,useRef 管持久引用,useMemo/useCallback 管缓存,useContext 管跨层通信,useReducer 管复杂状态。
8. 组件通信
8.1 父传子
用 props。
8.2 子传父
父组件传回调,子组件调用回调把数据传回去。
8.3 兄弟组件通信
通过共同父组件中转。
8.4 跨层级通信
优先考虑:
- Context
- 状态提升
- 业务状态库
8.5 常见通信方式总结
| 场景 | 推荐方式 |
|---|---|
| 父到子 | props |
| 子到父 | 回调函数 |
| 兄弟组件 | 状态提升 |
| 跨层级共享 | Context |
| 全局复杂状态 | Zustand / Redux Toolkit 等 |
8.6 记忆口诀
近的用 props,往上用回调,跨层用 Context,全局用状态库。
9. 状态管理选型
9.1 小项目:useState + Context
适合:
- 项目体量小
- 全局状态不多
- 状态结构简单
优点:
- 轻量
- 无额外依赖
- 容易上手
缺点:
- 拆分不好时,容易导致大范围更新
- 中大型项目会逐渐混乱
9.2 中项目:Zustand / Jotai
适合:
- 希望轻量
- API 简洁
- 想降低模板代码
优点:
- 学习成本低
- 写法自然
- 通常比传统 Redux 更轻
9.3 大项目:Redux Toolkit
适合:
- 复杂状态流
- 多人协作
- 中大型业务系统
- 需要强约束、可追踪更新
优点:
- 结构清晰
- 生态成熟
- 更适合大型团队协作
9.4 选型建议
- 小项目不要过度设计
- 中项目优先考虑开发效率和可维护性
- 大项目更重视规范、可追踪性和协作成本
9.5 一句话记忆
小项目先别上重武器,中项目追求轻量顺手,大项目追求规范和协作。
10. React 18 高频知识点
面试里 React 18 仍然是高频重点,尤其是自动批处理、并发渲染、Suspense、过渡更新。
10.1 自动批处理
React 18 中,更多场景下的更新会自动批处理。
可以先这样理解:
- 多次状态更新不一定触发多次渲染
- React 会尽量合并同一批次里的更新
- 这样能减少不必要渲染
10.2 并发渲染
并发渲染不是“多个线程一起渲染”,而是:
React 可以让渲染工作变得可中断、可恢复、可按优先级调度
这为更流畅的交互提供基础。
10.3 Suspense 增强
Suspense 可以帮助处理异步加载状态,例如组件懒加载。
const UserPage = React.lazy(() => import("./UserPage"));
function App() {
return (
<React.Suspense fallback={<div>加载中...</div>}>
<UserPage />
</React.Suspense>
);
}
10.4 过渡更新
React 18 提供了过渡更新相关能力,比如 startTransition、useTransition。
作用:
把“不那么紧急”的更新标记为低优先级,让用户输入等高优先级交互更流畅。
const [isPending, startTransition] = useTransition();
function handleChange(value) {
setInput(value);
startTransition(() => {
setKeyword(value);
});
}
10.5 useDeferredValue
用于延迟某个值的更新,让界面更顺滑。
适合:
- 搜索联想
- 大列表过滤
- 输入与重计算解耦
10.6 React 18 高频问法
- React 18 自动批处理是什么
- 并发渲染是什么,不是什么
startTransition解决什么问题- Suspense 有什么价值
10.7 记忆口诀
自动批处理减少重渲染,并发渲染让更新可打断,Suspense 管等待态,Transition 管优先级。
11. 性能优化手段
11.1 先记住性能优化的原则
React 性能优化不是到处加 Hook,而是先定位问题。
优化顺序建议:
- 先确认是否真的有性能问题
- 再看是否是不必要渲染
- 再看是否计算过重
- 最后再上缓存或拆分手段
11.2 React.memo
React.memo 用于缓存组件,在 props 没变时跳过不必要渲染。
const Child = React.memo(function Child({ name }) {
console.log("Child render");
return <div>{name}</div>;
});
适合:
- 组件纯渲染
- props 稳定
- 渲染成本相对高
11.3 useMemo / useCallback
这两个不要滥用。
什么时候值得用:
- 缓存开销明显小于重复计算成本
- 能实际减少子组件无意义渲染
- 依赖稳定且收益明确
11.4 状态下沉与状态提升
很多重渲染问题,不是 Hook 不够,而是状态放错位置。
原则:
- 谁需要,谁持有
- 尽量让高频变化状态靠近使用它的组件
- 不要把局部状态无脑提升到最顶层
11.5 代码分割
通过 React.lazy + Suspense 或路由级拆分减少首屏体积。
11.6 虚拟列表
大列表渲染时,只渲染可视区域,避免一次性挂载过多 DOM。
适合:
- 商品列表
- 聊天记录
- 后台表格
11.7 key 的合理使用
稳定 key 能减少错误复用,也能减少不必要的节点变动。
11.8 避免在 render 中创建重计算
例如:
- 大数组排序
- 复杂过滤
- 深度对象转换
可以考虑:
- 预处理
useMemo- 后端分页
- 虚拟滚动
11.9 性能优化答题模板
面试里可以这样答:
- 合理拆分组件,控制渲染范围
- 使用
React.memo、useMemo、useCallback减少不必要渲染 - 对大列表使用虚拟列表
- 使用代码分割优化首屏
- 结合 React 18 的过渡更新改善交互流畅度
12. 高频面试题
12.1 React 和 Vue 的核心差异怎么答
可简答为:
- React 更偏函数式和 UI 组合
- React 核心是状态驱动 + JSX
- React 更强调“你自己组织应用”,生态选择更自由
12.2 React 中为什么不直接修改 state
答:
- React 更依赖不可变更新来识别变化
- 直接修改可能导致视图不更新
- 也会让状态流变得难以追踪
12.3 useEffect 和 useLayoutEffect 区别
useEffect在浏览器绘制后执行useLayoutEffect在 DOM 更新后、绘制前同步执行
适合:
useEffect处理大多数副作用useLayoutEffect处理布局测量、同步 DOM 调整
12.4 React.memo、useMemo、useCallback 区别
React.memo缓存组件useMemo缓存值useCallback缓存函数
12.5 useState 和 useReducer 怎么选
- 简单状态用
useState - 状态变化逻辑复杂时用
useReducer - 多个状态相互关联时,
useReducer更清晰
12.6 为什么 key 不能随便用 index
答:
当列表项顺序变化时,React 会错误复用节点,导致输入错位、状态错乱和多余更新。
12.7 Context 会导致什么问题
如果 Context 的 value 频繁变化且作用范围很大,会让大量消费组件重新渲染。
12.8 React 18 新特性有哪些
高频答法:
- 自动批处理
- 并发渲染能力增强
- Suspense 能力增强
- 过渡更新
12.9 面试时推荐回答结构
- 先说定义
- 再说原理
- 再说场景
- 最后说注意点
例如回答 useMemo:
- 它用于缓存计算结果
- 本质是在依赖不变时复用上一次结果
- 适合昂贵计算
- 但不应滥用,因为本身也有维护成本
13. 6 小时学习规划
第 1 小时:React 核心心法
目标:
- 搞懂声明式 UI
- 搞懂组件化
- 搞懂
UI = f(state)
必须掌握:
- 组件是什么
- props 和 state 区别
- 单向数据流
第 2 小时:JSX、事件、列表、表单
目标:
- 熟悉 JSX 规则
- 掌握条件渲染和列表渲染
- 搞懂受控和非受控组件
必须掌握:
map + keyonChange + value- 子传父回调
第 3-4 小时:Hooks 核心
目标:
- 吃透
useState - 吃透
useEffect - 理解
useRef、useMemo、useCallback - 理解
useContext、useReducer
必须掌握:
- 为什么 Hook 不能条件调用
- 为什么 effect 需要清理
useMemo和useCallback区别
第 5 小时:React 18 + 性能优化
目标:
- 掌握自动批处理
- 理解并发渲染与过渡更新
- 掌握 React 常见优化点
必须掌握:
React.memo- 代码分割
- 虚拟列表
- 状态下沉
第 6 小时:复盘 + 面试表达
建议:
- 默写一个完整的表单组件
- 默写一个
useReducer示例 - 讲清楚 React 18 的 4 个关键词
- 讲清楚
useEffect、useMemo、useCallback
14. 一页速记总结
14.1 React 主线
- 组件化
- 数据驱动视图
- 单向数据流
14.2 基础 API
props:组件输入state:组件内部状态children:组件插槽内容
14.3 Hooks
useState:状态useEffect:副作用useRef:持久引用useMemo:缓存值useCallback:缓存函数useContext:跨层传值useReducer:复杂状态
14.4 React 18
- 自动批处理
- 并发渲染
- Suspense 增强
- 过渡更新
14.5 优化
- 组件拆分
React.memouseMemo/useCallback- 代码分割
- 虚拟列表
- 状态下沉
15. 背诵口诀
15.1 React 基础口诀
UI 跟着状态走,组件负责组合,props 往下传,回调用来往上走。
15.2 Hooks 口诀
状态用 state,副作用用 effect,持久引用用 ref,缓存值和函数用 memo、callback。
15.3 React 18 口诀
批处理减少渲染,并发更新可打断,Suspense 管等待,Transition 分轻重。
15.4 性能优化口诀
先找问题,再做缓存;先拆组件,再谈优化。
16. 最后给你的建议
想真正快速学会 React,建议按下面节奏练:
- 先手敲 3 个小组件:计数器、表单、列表
- 再手敲 3 个 Hook 场景:请求、定时器、缓存
- 再手敲 1 个 Context + reducer 的小案例
- 最后整理 React 18 和优化题答题模板
真正学会的标准不是“看懂”,而是:
- 你能自己写组件
- 你能自己拆状态
- 你能解释每个 Hook 解决什么问题
- 你能说出优化应该从哪下手
把这些打通后,你的 React 使用层能力就很稳了。