React 批判 2 则

React 哲学号称一套一套的,我也总结过一部分。React 的某些设计确实是挺巧妙的,但这只是 React 的其中一面。

某些情况下,这些说辞真的是一种对 React 的"自适应",换言之,找理由来掩饰 React 的设计缺陷。在某些场景下,这些设计缺陷会变得很难绕过,甚至绕不过,要不怎么说用 React 心智负担高呢。

事件的依赖

useEffect 依赖管理十分困难这件事众所周知,这个问题也算是其中一个特别难解决的分支。

举个例子,这里有一个非 React 原生库,想要包装成 React 组件。

viselect/packages/react/src/SelectionArea.tsx at master · simonwep/viselect

可以看到作者在封装的时候是没有把 useEffect 里所有使用的值都加入依赖,直接当初始化使用。当然一般情况下是没有问题的,但是如果你的传入的 props.onStart 里面引用了 useState 的变量呢?

那就完了。它不会生效的,因为该state更新时,这个 useEffect 根本不会更新,所以拿到的永远只有最开始的值。

例子,注意图中高亮区域:

如果把 props.onStart 加入了依赖又会怎么样呢?当然可以的,但是这又意味着整个初始化过程会重复运行,这简直毫无意义,纯纯的嫌用户电脑性能太高。

那到底怎么办?你可以把函数里面用到的会变化的值统统换成 ref,这样能用,不过非常难看,我们接着看。

其实有比较官方、也优雅一点的办法的:使用 useEffectEvent,至少它现在还叫这个名字,因为 React 到 19 发布为止,它都还是个实验性功能。

useEffectEvent 里面的函数不需要写依赖,依然能让所有使用的值是最新的。使用的场景就基本针对于上述的"事件触发"场景。

官网给出的示例代码:

tsx 复制代码
function ChatRoom({ roomId, theme }) {
  const onConnected = useEffectEvent(() => {
    showNotification('Connected!', theme);
  });

  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.on('connected', () => {
      onConnected();
    });
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]); // ✅ All dependencies declared
  // ...

清理顺序

useEffect() parent-child cleanup order · Issue #16728 · facebook/react

useEffect 的清理看起来很优雅,所有相关代码都内聚在一个函数里。

然而,React 清理副作用时的顺序有点任性,有可能你在父组件清除函数已经把你要用的东西 destroy 了,子组件的清除函数还使用了被父组件 destroy 的对象,于是产生了很奇妙的错误,这又是一个对非 React 原生库接入非常不友好的一个点。

而且,这个问题 React 团队甚至是不打算解决的。一般情况,你可以冒着内存泄漏的风险不管它,如果你一定要解决的话,你就得自己写 workaround 来处理全局的 destroy 了。

所以

虽然 React 确实好用,但是在某些情况,例如你使用了非 React 原生的 UI 或事件库,确实不好用(废话文学)。

相关推荐
永远的个初学者16 分钟前
图片优化 上传图片压缩 npm包支持vue(react)框架开源插件 支持在线与本地
前端·vue.js·react.js
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ17 分钟前
npm i / npm install 卡死不动解决方法
前端·npm·node.js
Kratzdisteln20 分钟前
【Cursor _RubicsCube Diary 1】Node.js;npm;Vite
前端·npm·node.js
杰克尼38 分钟前
vue_day04
前端·javascript·vue.js
明远湖之鱼1 小时前
浅入理解跨端渲染:从零实现 React DSL 跨端渲染机制
前端·react native·react.js
悟忧2 小时前
规避ProseMirror React渲染差异带来的BUG
前端
小皮虾2 小时前
小程序云开发有类似 uniCloud 云对象的方案吗?有的兄弟,有的!
前端·javascript·小程序·云开发
Android疑难杂症2 小时前
鸿蒙Notification Kit通知服务开发快速指南
android·前端·harmonyos
T___T2 小时前
全方位解释 JavaScript 执行机制(从底层到实战)
前端·面试
阳懿2 小时前
meta-llama-3-8B下载失败解决。
前端·javascript·html