共 17 节,按顺序
- 125 分钟
什么是 React?
欢迎。如果你一行 JavaScript 都没写过,也不太清楚“框架”是什么,那你来对地方了。本课结束时,你会知道 React 是什么,会有一个小小的 React 项目在浏览器里跑着,还会改过你的第一个组件。这就是全部任务。我们不着急。
What React isComponents as functionsVirtual DOM intuitionRendering JSXCreating a Vite app - 230 分钟
JSX 与组件 (Components)
上一课里,你看到一个组件返回了看着像 HTML 的东西:return <h1>Hello, React</h1>;。那时你多半觉得有点不对劲。JavaScript 函数返回的是数字、字符串、对象这类值,它们可不返回尖括号。之所以能在 JavaScript 函数里直接写标记,是因为中间有一层叫...
JSX syntax rulesSingle root elementClassName vs classEmbedding expressions with {}Defining componentsComposing components - 330 分钟
属性 (Props)
到目前为止你写的每个组件都是写死的。Greeting 永远只向同一个名字打招呼,Card 永远只显示同一段文字。做演示够用,但这完全违背了组件存在的意义:写一次,然后在很多地方带着不同的内容复用。一个只会问候 “Sam” 的 Greeting...
Passing props as attributesReceiving props objectDestructuring props in signatureDefault valuesThinking about prop shapes - 435 分钟
使用 useState 管理状态 (State)
到目前为止你写的每个组件,只要传进去的属性相同,渲染出来的结果就永远相同。对一个标题或一张卡片来说这没什么问题,但只要需要让用户盯着页面就能改动点什么,它立刻就撑不住了:点一下就往上加的计数器、能来回翻转的开关、把你刚敲进去的内容显示出来的文本框。普通的 JavaScript...
UseState hookReading stateCalling the setterUpdater function formNever mutate stateCounter pattern - 530 分钟
处理事件
一个只会依据属性和状态来渲染的组件,本身还谈不上可交互:必须有东西察觉到用户点了按钮、在字段里打了字或者按了某个键,并把这个动作转成一次状态更新。上一课你已经接过一个 onClick,当时没有停下来解释它。这一课会放慢节奏,认真看看 React...
OnClick handlerOnChange basicsPassing functions vs calling themEvent objectPassing handlers as props - 630 分钟
条件渲染与列表
你用过的几乎每一个界面,都会根据某个条件显示这个而不是那个:一条"你有新消息"的横幅,只有在真的有新消息时才出现;一个加载中的转圈图标,只在加载过程中显示。而几乎每一个界面也都会显示不止一个东西:一列订单、一格一格的商品、一条动态里的帖子。如果你把组件写死成"第一项、第二项、第三项",那只能撑到第四...
&& for show/hideTernary for either/orMapping arrays to JSXThe key propWhy keys need to be stable - 735 分钟
表单与受控输入 (Controlled Inputs)
在普通的 HTML <input> 里敲一个字母,浏览器自己就把事情办完了:DOM 元素悄无声息地记住你输入的内容,不必告诉别人。只要应用不需要知道框里此刻装着什么,这样就够用了。可是一旦你要校验它、要在内容看起来不对时禁用按钮、或者要在提交时把它发到别处,“浏览器把它记在某个地方”就不够了,组件必...
Controlled input patternValue and onChange togetherMulti-field form stateOnSubmit and preventDefaultGathering form data - 840 分钟
使用 useEffect 实现副作用 (Effects)
到目前为止,组件的工作一直是:看一眼自己当前的属性 (props) 和状态,然后回答一个问题,此刻屏幕上该显示什么。只要输入相同,这个答案每次都应该一模一样,就像计算器算 2 +...
What counts as a side effectUseEffect signatureDependency arrayRunning on mount onlyCleanup functionSubscribe/unsubscribe pattern - 940 分钟
数据获取
真实的应用几乎没有哪个能只靠用户屏幕上已有的数据活下去。总有那么一刻,某个组件需要向服务器要点东西:一份用户列表、某个商品的详情、一页搜索结果。在答案回来之前,有一段时间组件手里什么都没有,而且答案完全有可能因为网络出问题而永远回不来。一个只会渲染“数据”的组件,碰上这两种再平常不过的情况中的任何一...
Fetch inside useEffectLoading/error/data statesAbortController cleanupPreventing setState after unmountMention TanStack Query as a next step - 1035 分钟
组件组合 (Component Composition)
你做了一张带边框和阴影的卡片,看着挺不错。现在你还要用同样的卡片去包一张照片,去包一个登录表单,再去包一串评论。这时候很容易做的事,是把卡片复制三份,或者给它加上能想到的每一种内容对应的属性:title、photoUrl、formFields、comments。这两条路的尽头,都是一个谁都不愿意去碰...
Children propWrapping componentsPassing JSX as propsLifting state upThinking in component trees - 1135 分钟
Context 与 useContext
你的应用有一个深色模式开关。开关本身在设置面板里,可真正需要知道这个值的,是页面里一张卡片、卡片里一张表格、表格里往下第八层的一个按钮。想靠属性把值从这头传到那头,中间每一个组件都得接收一个自己根本用不上的 theme...
CreateContextContext.ProviderUseContextWhen context is the right toolContext vs prop drilling tradeoffs - 1235 分钟
useReducer
结账表单一开始都很简单。先有一个值,于是加一个 useState。接着需要一条错误提示,那就再加一个 useState。然后是“正在加载”的标记,再然后是“用户有没有碰过这个字段”的标记,到这一步,四份彼此独立的状态要由六个不同的事件处理器按正确的组合去更新。提交时要把加载标记置为...
When to reach for useReducerReducer function shapeAction objectsDispatchCombining useReducer with useContext - 1335 分钟
自定义钩子 (Hooks)
你写过一个能开能关的抽屉面板。三行 useState,加一个把布尔值翻过来的处理函数。接着下拉菜单也是同一套,弹窗又是同一套,「显示更多」链接还是同一套。现在有四个组件装着同样的六行代码,等你决定这个开关还应该记住上一次的状态,就得四处全改一遍,然后漏掉一处。
Extracting stateful logic into a functionUse prefix conventionUseToggle exampleUseLocalStorage exampleHooks rules - 1435 分钟
性能与记忆化 (Memoization)
你的应用里有一张两千行的表格,上面还有一个搜索框。每敲一个键都很沉重:你打字,半秒钟之后字母才出现在屏幕上。没有任何东西坏掉,代码看上去也很合理。真正发生的事情是,搜索框里的一个字符让 React 把那两千个行组件全部重新执行一遍,算出其中几乎没有一个发生了变化,然后再去更新屏幕。
React.memo for componentsUseMemo for expensive computationsUseCallback for stable function referencesWhen memoization is overkillMeasuring before optimizing - 1540 分钟
使用 React Router 进行路由
到目前为止你写出来的东西都待在同一个地址上。整个应用只有一个页面,想让用户看到什么,就用状态把它显示出来或藏起来。这样做能撑一阵子,直到有人想把设置界面收藏成书签,或者想把某一个用户的链接发给同事,又或者按下浏览器的后退按钮却没有回到自己预期的位置。一个不理会地址栏的网页应用,等于白白丢掉了每个用户...
Installing react-router-domBrowserRouterRoutes and RouteLink for navigationUseParamsUseNavigate - 1640 分钟
测试 React 组件 (Components)
你改了共享组件里的一行代码,然后花二十分钟在应用里到处点,确认别的地方没被弄坏。下周再改一次,又是同样的二十分钟。到最后你干脆不再动它了,因为每次都要这样核查一遍,实在不划算,于是代码就围着这块没人敢碰的地方慢慢烂掉。
Vitest + React Testing Library setupRender and screenGetByRole queriesUserEvent for interactionsWriting one good button test - 1760 分钟
顶点项目:待办事项应用
到目前为止,每一课都只塞给你一个想法,外加一个围着它转的小例子。真实的应用不是这样。在真实的应用里,状态、列表渲染、表单、持久化和 URL 全都要同时存在于同一个代码库中,而难的地方不在于其中任何单独一块,而在于决定每一块该放到哪儿。
Combining state, lists, controlled inputsCustom hook for localStorage persistenceSmall routing setupPutting it together
用你的语言学习 React
每一节课、测验和导师回复都以你的语言显示。AI 导师会用你提问的语言来回答。
Roles that use React
See how hiring teams interview engineers on React, in production-like environments.
Frontend Engineer (React, Angular, Vue)
Hire frontend engineers in real workspaces with Vite, real component libraries and real performance budgets. Live or take-home, fully recorded.
See the interviewFull Stack Developer
Hire full stack developers in real apps with real APIs, real UIs and real tests. Live or take-home, fully recorded.
See the interviewWeb Application Engineer
Hire web application engineers in real apps with real routes, real auth and real test suites. Live or take-home, fully recorded.
See the interview