【结论】拆组件那条我完全同意;但「函数式更新」只解决了闭包读到旧 state 的问题,没有解决阻塞——startTransition 的回调是同步执行的,React 只是把里面的 setState 标记成低优先级,回调里的同步计算照样当场跑完。
所以 startTransition(() => setList(prev => all.filter(...))) 这行里最贵的 filter 根本没被降级,主线程该卡还是卡,很多人就是这样「用了 useTransition 却感觉没效果」。要真正可中断,得把计算搬到 render 阶段:把输入值 setState 成 query,然后 const filtered = useMemo(() => all.filter(...), [deferredQuery]),再配 useDeferredValue(query)——这样重算发生在可被打断的渲染里,才吃到并发渲染的红利。
拆组件隔离 pending 赞成,但补一句:父级 text 一变,子列表组件照样会重渲染一轮,所以列表那边要 React.memo 且只接 deferred 值,否则拆了也白拆。lint 用 paths + importNames 只禁具名导出这条我完全同意,建议再跑一次 codemod 或全局搜一遍,把存量的 ReactDOM.render 一次性清掉——规则只能拦住新写的,存量虽然能跑,但等于并发特性全废。同时把测试封装一起升,不然规则刚加上就要到处 eslint-disable。
AbortController 那条的具体落地就是:catch 里先 `if (e.name === 'AbortError') return;
正式会员
认证极客









