V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
594mantou
V2EX  ›  React

请教一个 React SSR 和自定义元素互操作的问题

  •  
  •   594mantou ·
    mantou132 · 350 天前 · 835 次点击
    这是一个创建于 350 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景:我将自定义元素导出成了 React 组件,让 React 项目轻松使用自定义元素。

    但问题是,如果使用 SSR ,React 在进行水合时并不会为自定义元素设置 Properties ,这导致自定义元素不能正常工作,例如: https://nextjs-learn-phi-henna.vercel.app/ce-test

    • 颜色选择器不能改,因为事件没有注册上去
    • 卡片的标题没有显示,因为标题不是 attribute 而是作为 property 定义的(这在自定义元素中是很常见的,比如 table 这样的复杂元素,数据不可能用 attribute 表示)

    点击 “← Back to home” 回到首页再点击 “Custom Element Test” 回到这个页面时,自定义元素正常工作了,因为这时候使用了客户端渲染。

    我尝试在 hydrateInstance 中添加 setInitialProperties 可以解决这个问题:

    function hydrateInstance(instance, type, props, hostContext, internalInstanceHandle, shouldWarnDev) {
      ...
    
      // 水合时立即为自定义元素设置 properties
      if (isCustomElement(type)) {
        setInitialProperties(instance, type, props);
      }
    }
    

    这是适合的解决方案吗(我没有通篇阅读 React 源代码)?如果可以的话我应该去哪个 React 社区提这个建议,因为我使用的是 react@experimental,并不是 React 正式版。

    7 条回复    2024-01-22 22:22:58 +08:00
    theprimone
        2
    theprimone  
       332 天前
    之前我有想法尝试 custom element ,但是想想会不会 SSR 问题不小,所以 OP 解决 SSR 问题了吗?
    594mantou
        3
    594mantou  
    OP
       327 天前
    @theprimone 没有,在等 React 更新 19 。另外,我生成 React 组件的时候添加了一些代码解决了水合的问题。

    https://duoyun-ui.gemjs.org/zh/guide/integrate#react

    在 SSR 项目中使用自定义元素应该也是可以的,基本布局都是 div ,只有一些按钮、弹窗之类的组件不会破坏布局。

    依赖 `:defined` 伪类也能保证不会破坏页面

    如果整个页面都是自定义元素(有 ShadowDOM ),还想要 SSR 的话只能依赖声明式 ShadowDOM 自己做了,市面上应该有预渲染之类的方案,用 jsdom 模拟生成 ShadowDOM 理论上也行。
    theprimone
        5
    theprimone  
       327 天前
    @594mantou #3 那我怎么有个印象好像很早的 React 文档就在说 custom element 的问题了,意思是以前一直都只是支持客户端渲染而已吗 😂
    594mantou
        6
    594mantou  
    OP
       326 天前
    594mantou
        7
    594mantou  
    OP
       303 天前
    @0.0.0-experimental-feed8f3f9-20240118 似乎修复了。

    所以真要等 19 正式发布。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3039 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 13:19 · PVG 21:19 · LAX 05:19 · JFK 08:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.