前端面试 P083:函数式更新、队列与纯度
Showing the original in Chinese (China)
来源:方格前端讲面试 · 13.使用 useState 的函数式更新方式能带来哪些好处?,11 分 20 秒。
回看定位:02:28 三次更新 · 07:14 函数队列 · 07:25 复杂度的原说法
值替换与更新函数
同一渲染 count 为 0 时,连续三次 setCount(count + 1) 都请求设置为 1;连续三次 setCount(previous => previous + 1) 则把前一项计算结果传给后一项,得到 3。
const updates = [value => value + 1, value => value + 1, value => value + 1];
console.log(updates.reduce((value, update) => update(value), 0)); // 3
这个例子解释组合语义,不是 React 队列内部实现的完整展开。更新还可混合替换值与函数,顺序会影响最终结果。
“最新”只针对相应排队状态
updater 得到处理到该位置的 pending state,不会顺便让闭包里的其他 props、请求参数或其他 state 自动变最新。多份状态强相关时可考虑合并结构或 reducer。
updater 必须纯,不要在里面请求、打业务日志或执行外部变更;开发 StrictMode 可以再次调用它检查问题。
必须纠正两个推论
视频说函数式更新的时间空间复杂度都是常数,不适用于任意 updater、队列长度或数据结构。复制大数组、计算复杂对象当然有成本。
只暴露原始 setter 也不能限制调用方“只能函数式更新,不能覆盖状态”,因为 setter 本来同时接受两种形式。若要限制行为,应暴露 increment、reset 等明确业务接口。
需要根据旧值计算时,函数式形式清楚可靠;新值直接来自输入或接口结果时可传值。也不要把所有正常快照都叫“闭包陷阱”。
依据:React:更新队列。