动手做Get your hands on it
练习跟着课文走 —— 每节课尾都有本课的练习。这一页是全部练习的总库,想集中刷题的时候来。 每个练习都写清了它来自哪一节,卡住了就回去看那一节。Practice follows the lessons — every lesson ends with the exercises for that lesson. This page is the whole library, for when you want to drill in one sitting. Each exercise names the lesson it came from, so you can go back when you stall.
已筛到你正在学的《React 考试》。想看全部就点上面的「全部」。Filtered to React exam — the course you are on. Use “All” above to see everything.
练习Exercises
筛出 54 个练习(共 148 个) · 第 3 / 5 页。Showing 54 of 148 · page 3 / 5.把 handleEdit 和 handleSubmitNote两个函数完整写出来(含 Task 1 的分支)。 这是 Q1 的完整答案,写对了这道题就通了。
Write both handleEdit and handleSubmitNote in full, including the Task 1 branch. This is the complete answer to Q1: get it right and the question is done.
- handleEdit:把这条笔记设为「正在编辑」,不要改动 noteshandleEdit: mark this note as the one being edited, and leave notes alone
- handleSubmitNote 编辑分支:按 id 就地替换,位置和顺序不变handleSubmitNote, edit branch: replace by id in place, keeping the position and the order
- handleSubmitNote 编辑分支:替换完要退出编辑模式handleSubmitNote, edit branch: leave edit mode once the replace is done
- handleSubmitNote 新增分支:追加到末尾handleSubmitNote, add branch: append to the end
- 全部使用函数式更新,不许修改原数组Use functional updates everywhere, and never change the original array
看答案之前,先确认你已经自己动手写过一遍。看懂别人的答案和自己写出来,是两种能力。Before you open this, make sure you have written it yourself once. Following someone else's answer and producing your own are two different skills.
点 Edit,输入框正常回填,按钮变成 Update。 改完内容点 Update —— 列表一点变化都没有, 表单也没清空。控制台干净。
Click Edit and the inputs prefill correctly, and the button becomes Update. Change the content and click Update — the list does not change at all, and the form does not clear either. The console is clean.
下面哪个 handleDelete 能让四个测试全部通过, 但明显违反题目要求?
Which handleDelete below makes all four tests pass while clearly breaking what the task asks for?
你写的 handleSubmitNote 是 setNotes((prev) => [...prev, submittedNote]), 但自己加的测试报「找不到 My Title」。 测试代码是 userEvent.click(btn); expect(list).toHaveTextContent("My Title")。 最可能的原因?
Your handleSubmitNote is setNotes((prev) => [...prev, submittedNote]), but the test you added reports that My Title cannot be found. The test code is userEvent.click(btn); expect(list).toHaveTextContent("My Title"). What is the most likely reason?
现有测试测不出「按 id 删除」。写一个新测试: 添加两条同名笔记,删掉其中一条, 断言另一条还在。
提示:两条数据时页面上有两个 Delete 按钮,getByRole 会因为「找到多个」而抛错 —— 得用 getAllByRole。
The existing tests cannot check the delete by id. Write a new test: add two notes with the same title, delete one of them, and assert that the other is still there.
A note: with two notes there are two Delete buttons on the page, and getByRole throws because it found more than one. Use getAllByRole.
- 添加两条 title 完全相同、content 不同的笔记Add two notes with exactly the same title and different content
- 用 getAllByRole 拿到 Delete 按钮数组,点第一个Use getAllByRole to get the array of Delete buttons, then click the first one
- 断言 notes-list 不再含「内容A」Assert that notes-list no longer holds 内容A
- 断言 notes-list 仍然含「内容B」Assert that notes-list still holds 内容B
- 所有 userEvent 调用都要 awaitPut an await on every userEvent call
看答案之前,先确认你已经自己动手写过一遍。看懂别人的答案和自己写出来,是两种能力。Before you open this, make sure you have written it yourself once. Following someone else's answer and producing your own are two different skills.
假设签名改成 runTasks(promises: Promise<T>[], limit: number), 调用方写 runTasks([task1(), task2(), task3()], 2)。 会发生什么?
Suppose the signature becomes runTasks(promises: Promise<T>[], limit: number) and the caller writes runTasks([task1(), task2(), task3()], 2). What happens?
有人写 return Promise.allSettled(tasks.map((t) => t()))。 它满足几条要求?
Someone writes return Promise.allSettled(tasks.map((t) => t())). How many of the requirements does it meet?
五个空。第 2 个和第 4 个是最容易写错的 —— 一个关系到「顺序」,一个关系到「任务到底有没有被启动」。
Five blanks. Numbers 2 and 4 are the ones most often written wrong: one decides the order, the other decides whether the task was started at all.
只给签名。这是 Q2 的完整答案,写对了这道题就通了。 写完可以在本机 npm run q2 验证。
You get only the signature. This is the complete answer to Q2: get it right and the question is done. When you finish you can check it here with npm run q2.
- 同一时刻最多 limit 个任务在运行At most limit tasks are running at the same time
- 某个任务结束后,立刻启动下一个(不是等一批都结束)As soon as one task finishes, start the next one (do not wait for a whole batch)
- 任何任务失败都不能让整体抛错No failing task may make the whole call throw
- 返回数组的顺序必须与 tasks 一致The order of the returned array must match tasks
- 成功写 { status: "fulfilled", value },失败写 { status: "rejected", reason }On success write { status: "fulfilled", value }; on failure write { status: "rejected", reason }
看答案之前,先确认你已经自己动手写过一遍。看懂别人的答案和自己写出来,是两种能力。Before you open this, make sure you have written it yourself once. Following someone else's answer and producing your own are two different skills.
跑 npm run q2,没有报错,但一行task N START 都没有,直接就出结果了 —— 而且结果里的 value 长得很奇怪。
You run npm run q2. Nothing reports an error, but not one task N START line appears; the results come out right away. And the value in each result looks strange.
四个空。第 2 个是「只改一个字段」的写法,第 4 个考的是 「全选」和「反选」的区别。
Four blanks. The second is how you change one field only. The fourth is about the difference between select-all and invert-selection.
已有 todos 和 filter 两个 state。 写出可见列表和「清除已完成」,注意筛选态下的写操作该作用于谁。
You already have the two states todos and filter. Write the visible list and the clear-completed action, and think about which list a write should act on while a filter is on.
- visible 是派生数据,不许用 useState 或 useEffectvisible is derived data: no useState and no useEffect
- filter 为 "all" 时显示全部,"active" 显示未完成,"done" 显示已完成When filter is "all" show everything, "active" shows the unfinished ones, "done" shows the finished ones
- clearDone 移除所有已完成项,保留未完成项clearDone removes every finished item and keeps the unfinished ones
- 写操作必须作用于 todos,不能作用于 visibleA write has to act on todos, never on visible
- 不许修改原数组Do not change the original array
看答案之前,先确认你已经自己动手写过一遍。看懂别人的答案和自己写出来,是两种能力。Before you open this, make sure you have written it yourself once. Following someone else's answer and producing your own are two different skills.