本章属于 React 教程的核心路线。建议先通读概念模型,再手写最小示例,最后用练习验证自己能否独立复现。
本章目标
本章掌握组件组合、children、Panel 插槽模式、createContext、Provider,以及什么时候才需要 Context。
阅读本章时,请把每个 API 放回“数据如何变成界面、用户操作如何改变数据”的主线中理解。React 的学习重点不是背诵语法,而是建立可预测的渲染模型。
- 识别本章概念在真实组件中的位置
- 能写出一个最小可运行示例
- 能解释常见错误为什么发生
概念模型
组合优先意味着先通过组件嵌套表达结构,再考虑全局共享。Context 适合主题、登录用户、语言等跨层稳定数据,不适合替代所有 props。
你可以把 React 程序看成一棵由组件组成的元素树。每次输入数据、状态或外部系统发生变化,React 会重新计算需要展示的 React element,再用高效的方式更新浏览器中的 DOM。
最小示例
Panel 组件通过 children 接收内容;ThemeContext 通过 Provider 向深层组件传递主题。
import { createContext, useContext } from "react";
const ThemeContext = createContext("light");
function Panel({ children }: { children: React.ReactNode }) {
return <section className="panel">{children}</section>;
}
function Toolbar() {
const theme = useContext(ThemeContext);
return <button className={theme}>保存</button>;
}
export function SettingsPage() {
return (
<ThemeContext.Provider value="dark">
<Panel>
<Toolbar />
</Panel>
</ThemeContext.Provider>
);
}
type LessonNote = { title: string; done: boolean };\nconst note: LessonNote = { title: 'React 教程', done: false };
规则与陷阱
规则的价值在于让多人维护同一个项目时仍能预测行为。下面这些限制看似细碎,实际都在保护组件的输入、输出和生命周期边界。
- 能用 children 组合解决的问题,不要过早引入 Context。
- Context value 频繁变化会让消费者重新渲染。
- Provider 的范围越小越容易推理。
- 不要把所有应用状态塞进单个 Context。
练习
练习应当先小后大:先验证一个概念,再把它接入完整页面。不要在没有理解失败原因时复制更复杂的代码。
- 实现 Panel,并用 children 放入任意内容。
- 创建一个 Theme Context 和 Provider。
- 比较 props 传递和 Context 传递在三层组件中的可读性。