跳到主要内容

第 33 章:破坏性变更与移除——19 删掉了什么,为什么

React 19 是大版本,大版本的意义不只是加新功能,更是清账:把历史包袱、有隐患的 API、被新写法取代的东西一次性删掉。本章看它删了什么、为什么删。

先记住这一句:19 的删除分三类:被新写法替代的(ReactDOM.render、forwardRef)、本身有隐患的(字符串 ref)、维护成本高没人用的(propTypes、函数组件 defaultProps)。删除的标准是"留下它比删掉它更贵"。

一图流:三类删除

第一类:被替代的写法

ReactDOM.render / ReactDOM.hydrate 删除。第 1 章讲过,19 唯一的入口是 createRoot / hydrateRootrender 的"直接往容器里渲染"没有返回根对象的概念,天生和并发不兼容,所以删掉,逼你用能"update/unmount"的根对象。这是"并发需要根"的必然结果。

forwardRef 废弃。第 2 章讲过,19 里 ref 成了普通 prop,函数组件直接收 props.refforwardRef 这个包装函数就没了存在意义。它没被删(兼容存量),但新代码不该再用。

React.createFactory 删除。JSX 转换普及后没人手写工厂函数了。

第二类:有隐患的

字符串 ref 删除。老写法 ref="name" 通过字符串定位实例,容易在组件间串位、难以类型化,是长期的安全和正确性隐患。19 直接移除,只保留 ref={fn}ref={object}

element.ref 访问废弃。第 2 章说过,元素的 ref 字段在 19 里成了带废弃警告的兼容 getter(真值在 props.ref)。这是为未来彻底移除 element.ref 铺路。

第三类:维护成本高

propTypes 移出 React。运行时类型检查的价值被 TypeScript 取代,而 propTypes 给每个元素解析、验证,是纯运行时开销。19 把它从 react 包里移除,需要的人去用独立方案。

函数组件的 defaultProps 删除。Class 组件仍支持,但函数组件上的 defaultProps 在 19 被移除(用默认参数代替)。原因:函数组件的默认值用 function Foo({x = 1}) 更符合 JS 习惯,defaultProps 是历史包袱。

findDOMNode 删除。它靠"从组件找到真实 DOM"的魔法路径,破坏了封装,也阻碍并发。用 ref 替代。

行为收紧:不是删,是更严

  • useRef 必须传参useRef() 缺参数直接报错,防止忘传导致 undefined。
  • act 必须 await:测试里的 act 现在是异步 API,逼你把副作用 flush 干净。
  • 错误处理 API 变化onUncaughtError / onCaughtError / onRecoverableError 成了 createRoot 的正式选项(第 1 章见过),componentDidCatch 的边界行为更明确。

为什么值得

删除的共性:留下它,React 就要一直为它付运行时成本、维护成本、兼容成本。19 借着大版本把这些债还了:

  • 运行时更轻(没有 propTypes 验证、没有字符串 ref 查找)。
  • 并发更干净(没有和并发冲突的 legacy 入口)。
  • 心智更简单(一个入口、一个 ref 写法、一种类型方案)。

存量代码迁移的痛,换来的是新代码不再背着这些历史包袱。

动手实验

  1. 试被删的 API:在 React 19 项目里跑 ReactDOM.render、字符串 ref、函数组件 defaultProps,看控制台的报错/警告,对照"为什么删"。
  2. 看 forwardRef 废弃forwardRef 包一个组件,dev 下看废弃警告,再用"ref 进 props"的新写法对比。
  3. 试 useRef 缺参useRef() 不传参,看报错信息,理解"行为收紧"。

小结

  • 19 的删除三类:被替代、有隐患、没人用
  • 被替代:ReactDOM.rendercreateRootforwardRef→ref 进 props。
  • 有隐患:字符串 ref、element.ref 访问废弃。
  • 没人用:propTypes 移出、函数组件 defaultProps 删除、findDOMNode
  • 行为收紧:useRef 必传参、act 必 await。
  • 删除的标准是"留下比删掉更贵",换来更轻的运行时和更干净的心智。
  • 第七部分到此收尾。下一步第八部分工程与周边(第 34~36 章,选讲)。