Skip to content
目录

React 绑定与渲染层分离

1. 设计目标

Plate 不把 React 作为唯一运行环境。它区分:

  • 无 React 核心层withSlate / createSlateEditor
  • React 增强层withPlate / createPlateEditor / usePlateEditor

这让同一插件系统可以在服务端、静态处理、React 客户端里复用。

2. 代码证据

2.1 非 React 入口

  • packages/core/src/lib/editor/withSlate.ts
  • packages/core/src/lib/editor/createSlateEditor.ts

2.2 React 入口

  • packages/core/src/react/editor/withPlate.ts
  • packages/core/src/react/editor/usePlateEditor.ts
  • packages/core/src/react/plugins/react/ReactPlugin.ts

withPlate 会在 withSlate 基础上追加 React 核心插件(getPlateCorePlugins),而不是复制一套编辑器系统。

3. 为什么这种分层很重要

  1. 静态能力可独立演进:序列化、反序列化、规则处理不依赖 React 生命周期
  2. Hook 污染可控:React 专属逻辑集中在 React 插件层
  3. 调试边界清晰:出现“Invalid hook call”时能快速定位是不是把 React 插件带进了纯静态链路

4. 真实案例:serializeHtml Invalid Hook Call

Issue #2804 是非常典型的教学素材:

  • 现象:serializeHtml 场景触发 React hook 错误
  • 社区 workaround:过滤掉依赖 React 运行时的插件(如 blockSelectiontoggle
  • 启示:静态序列化链路要与 UI/交互插件解耦

这个问题不是“某个 if 写错了”,而是架构边界被混用导致的。

5. 可说的工程经验

  • 在编辑器系统里,“渲染层插件”与“数据层插件”必须明确分组
  • 不要拿生产编辑器完整插件数组直接喂给导出/静态化流程
  • 可以按场景建立插件 profile(edit profile / serialize profile)

6. 与 Base Plugin 重构的关系

PR #3526 的“Base plugin”方向,本质就在强化这种边界:基础行为与 UI 绑定分离,减少跨层耦合。

小结

Plate 的 React 绑定不是“包一层 hook”,而是完整的分层策略。真正理解这点,你就能解释很多看似零散的问题(SSR、序列化、hook 异常、插件复用)。

MIT License.