恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

LogicFlow React 自定义节点实战:使用 @logicflow/react-node-registry 注册 React 组件节点

  • 首页
  • 资讯中心
  • /
  • LogicFlow React 自定义节点实战:使用 @logicflow/react-node-registry 注册 React 组件节点

相关资讯

Rnote:开源手写笔记与草图应用|免费 5 分钟上手指南 2026/9/15 12:05:39
LifeOS 技术栈偏好指南:用 TECHSTACKPREFERENCES.md 约束 DA 的每一次代码建议 2026/9/15 12:05:39
AI产品上下文压缩技术解析与实践指南 2026/9/15 12:05:39

最新资讯

Flutter的simple_auth在鸿蒙平台的适配实践
Agent Zero 插件管理完全指南:从 Plugin Hub 浏览、安全扫描到安装、更新、卸载与激活
Halcon中rectangle2矩形仿射变换取顶点与边中点的方法
LifeOS TELOS 信念体系(Beliefs)实战指南:从模板占位符到 DA 决策底座
PyQt5 + PaddleOCR 桌面OCR标注工具实战解析
用 OpenCore Legacy Patcher 给老 Mac 升级 macOS 15 完整指南

今日推荐

GDPR下大数据架构重构与隐私保护实践
多组学数据平台架构设计与优化实践
企业主数据管理系统架构设计与实施全解析

本周热门

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化
Flutter应用改名全指南:从Android到iOS的配置与工具实践

本月精选

自研推理加速器Redwood:两周内实现PyTorch模型高效部署的实战教程
V4L2摄像头采集实战:从camera_client.rar到出图全流程解析
从“谁发明了钢琴键”到知识问答智能体:RAG与记忆工程实践

LogicFlow React 自定义节点实战:使用 @logicflow/react-node-registry 注册 React 组件节点

发布时间:2026/9/15 12:10:40
LogicFlow React 自定义节点实战:使用 @logicflow/react-node-registry 注册 React 组件节点 LogicFlow React 自定义节点实战使用 logicflow/react-node-registry 注册 React 组件节点【免费下载链接】LogicFlowA flow chart editing framework focus on business customization. 专注于业务自定义的流程图编辑框架支持实现脑图、ER图、UML、工作流等各种图编辑场景。项目地址: https://gitcode.com/GitHub_Trending/lo/LogicFlow本篇技术指南聚焦 LogicFlow 官方提供的高阶自定义节点方案logicflow/react-node-registry它将 React 组件直接注册为流程图节点内容让开发者复用系统内已有的组件库如 antd并借助 React 的开发体验快速产出业务节点。读完本文你将掌握register注册 API、ReactNodeProps数据契约、属性变更驱动的节点刷新机制以及解决 Context 穿透问题的 Portal 渲染模式并理解其底层与HTMLNode的差异和原理。为什么需要 React 节点注册机制LogicFlow 原生支持通过继承HtmlNode来扩展节点内容详见 HtmlNode 相关文档开发者可以自由渲染 DOM。但社区反馈表明这条路径存在两个明显的体验问题不够直观需要手工处理节点的挂载、更新与销毁生命周期存在性能隐患销毁时机处理不当会导致 DOM 泄漏或更新错乱。为此LogicFlow 将logicflow/react-node-registry作为独立包发布位于仓库 packages/react-node-registry它把「React 组件 ↔ 流程图节点」的桥接逻辑封装在框架内部。你只需要提供一个普通的 React 函数组件就能把它注册成可在画布中拖拽、连线、缩放的自定义节点。该方案天然带来两个能力复用既有组件生态antd、自定义业务组件等可以直接作为节点内容渲染享受 React 开发范式状态管理、Hook、条件渲染、组件化拆分等 React 特性在节点内全部可用。环境准备与安装logicflow/react-node-registry是一个 monorepo 中的独立包其peerDependencies声明了运行时依赖见 package.json依赖版本要求logicflow/core与当前仓库workspace:*匹配的版本react 18.0.0react-dom 18.0.0因此使用前需要保证项目中已安装 React 18 及以上版本。安装命令如下以 pnpm 为例本仓库使用 pnpm workspace 管理pnpm add logicflow/react-node-registry安装完成后从包入口src/index.ts可以导出以下内容register、ReactNodeProps、ReactNodeModel、ReactNodeView、Wrapper、Portal后续章节将逐一展开。核心 API 解析register 与 ReactNodeProps注册函数 registerregister是使用该包的核心入口其签名与实现位于 packages/react-node-registry/src/registry.tsexport function register(config: ReactNodeConfig, lf: LogicFlow) { const { type, component, effect, view: CustomNodeView, model: CustomNodeModel } config if (!type) { throw new Error(You should specify type in config) } reactNodesMap[type] { component, effect } lf.register({ type, view: CustomNodeView || ReactNodeView, model: CustomNodeModel || ReactNodeModel, }) }它接收两个参数configReactNodeConfig节点注册配置lfLogicFlow 实例注册目标可以是任意一个已初始化的实例。ReactNodeConfig的完整字段如下与LogicFlow.RegisterConfig相交集见 registry.ts字段类型是否必填说明typestring是自定义节点类型标识addNode时通过该值引用componentReact.ComponentTypeReactNodeProps是渲染节点内容的 React 组件effect(keyof LogicFlow.PropertiesType)[]否属性副作用过滤只有列出的属性变化时才触发组件重渲染view自定义 View 类否覆盖默认的ReactNodeView用于深度定制渲染逻辑model自定义 Model 类否覆盖默认的ReactNodeModel用于定制数据与样式逻辑从源码可以看出register内部做了两件事将component与effect存入模块级reactNodesMap供后续渲染层按type查表调用lf.register把默认的ReactNodeView/ReactNodeModel或其自定义子类注册到 LogicFlow 实例上。组件 props 契约 ReactNodeProps你的组件会被注入如下 props定义见 registry.tsexport type ReactNodeProps { node: BaseNodeModel graph: GraphModel }node当前节点的数据模型BaseNodeModel通过node.getData()或node.properties读取业务数据通过node.setProperty(...)回写数据graph所属画布的图模型GraphModel可用于访问整张图的其他节点、连线等。实战一将 React 组件渲染为节点内容基础示例下面是最小可运行示例来自官方文档并对应站点示例 sites/docs/src/tutorial/advanced/react/index.tsximport { FC } from react import LogicFlow from logicflow/core import { register, ReactNodeProps } from logicflow/react-node-registry // 1. 自定义 React 组件 const NodeComponent: FCReactNodeProps ({ node }) { const data node.getData() if (!data.properties) data.properties {} return ( div classNamereact-algo-node img src{require(/assets/didi.png)} altDiDi / span{data.properties.name as string}/span /div ) } // 2. 初始化 LogicFlow 实例 const lf new LogicFlow({ container: document.querySelector(#graph) as HTMLElement, grid: { size: 20 }, }) lf.render({}) // 3. 注册自定义节点 register( { type: custom-react-node, component: NodeComponent, }, lf, ) // 4. 添加节点 const node lf.addNode({ id: react-node-1, type: custom-react-node, x: 80, y: 80, properties: { name: Todays Trip, width: 120, height: 28, }, }) console.log(node ---, node)要点说明初始化顺序register必须在addNode之前调用否则 LogicFlow 找不到type对应的 view/modelproperties 即业务数据addNode传入的properties会原样进入node.getData().properties组件中读取的就是它。宽高等布局属性也建议放在properties中如示例中的width/heightReactNodeModel会在setAttributes()中消费这些值见 model.tsstyle 支持ReactCustomProperties继承了IHtmlNodeProperties并扩展了width、height、radius、refX/refY文字偏移、style/textStyle节点与文字样式等字段见 model.ts可在properties.style中传入覆盖主题样式。直接复用 antd 组件因为节点本质就是 React 组件站点示例中还演示了把 antd 组件直接当作节点使用const NextAntdNode: FC () { return ( Space directionvertical classNameantd-node-wrapper CheckCircleTwoTone twoToneColor#52c41a style{{ fontSize: 40 }} / ColorPicker defaultValue#1677ff sizelarge showText / Tooltip titleprompt text spanShow Tooltip/span /Tooltip /Space ) } register({ type: custom-antd-node, component: NextAntdNode }, lf) lf.addNode({ id: react-node-2, type: custom-antd-node, x: 500, y: 80, properties: { width: 130, height: 130 }, })底层渲染链路register把默认 view 指向ReactNodeView继承自HtmlNode见 packages/react-node-registry/src/view.ts。渲染流程如下LogicFlow 调用setHtml(rootEl)在节点根 DOMSVGForeignObjectElement内创建div.custom-react-node-content容器view.tsrenderReactComponent将组件包装进Wrapper后渲染到容器非 Portal 模式下使用createRoot(container).render(elem)view.tsWrapper见 wrapper.tsx按node.type从reactNodesMap取出注册的组件注入node、graph两个 props 后渲染并自动为函数组件/元素执行cloneElement节点尺寸自适应ReactNodeView通过ResizeObserver监听内容尺寸并以 80ms 节流回调measureAndUpdate把内容实际宽高回写进model.propertiesview.ts。这就是为什么示例中组件内容变大后节点框会自动跟着变大的原因。实战二属性变化驱动的节点刷新与HtmlNode行为一致当用户通过setProperties或setProperty修改节点属性时节点内容会自动更新。官方示例用定时器不断更新name来演示这一机制const node1 lf.addNode({ id: react-node-1, type: custom-react-node, x: 80, y: 80, properties: { name: Todays Trip, width: 120, height: 28, }, }) const update () { node1.setProperty(name, Todays Trip ${(this.count 1)}) this.timer setTimeout(update, 1000) } update() // 在 componentWillUnmount 中清除定时器避免组件卸载后仍触发更新 if (this.timer) { clearTimeout(this.timer) }刷新机制的实现原理自动刷新由Wrapper组件监听事件完成见 wrapper.tsxcomponentDidMount() { const { node, graph } this.props graph.eventCenter.on(EventType.NODE_PROPERTIES_CHANGE, (eventData) { const keys eventData.keys as string[] const content reactNodesMap[node.type] if (content eventData.id node.id) { const { effect } content // 未定义 effect 时默认更新定义 effect 时仅当命中 effect 列表中的属性才更新 if (!effect || keys.some((key) effect.includes(key))) { this.setState({ tick: this.state.tick 1 }) } } }) }两个关键设计值得注意事件驱动而非轮询Wrapper订阅EventType.NODE_PROPERTIES_CHANGE全局事件并校验eventData.id node.id只有自身节点属性变化才会触发重渲染effect 副作用过滤若注册时传了effect数组如effect: [name]则只有当变化的属性 key 命中该数组时才触发setState。对于包含高频变化属性如坐标、缩放的节点这可以显著减少无关重渲染是官方预留的性能优化开关。由于Wrapper是PureComponent同时配合 props 不变原则可以最大限度避免不必要的 React 重渲染。实战三Portal 模式解决 Context 穿透问题为什么需要 Portal上述默认渲染方式存在一个结构性局限React 组件被createRoot(container)渲染进节点自身的 DOM 容器脱离了应用正常的 React 渲染文档树。带来的直接后果是组件无法访问外部 React Context如主题、国际化、全局配置等 Provider 注入的数据与宿主应用共享的上下文机制如useContext在该模式下失效。如果你的业务节点需要读取外部 Context官方提供了Portal 模式它把节点内容以 React Portal 的形式挂载回应用的主渲染树从而恢复完整的 Context 上下文访问能力。Portal 模式示例完整示例见 sites/docs/src/tutorial/advanced/react/Portal.tsx核心代码如下import { FC, useContext } from react import LogicFlow from logicflow/core import { register, ReactNodeProps, Portal } from logicflow/react-node-registry // 注意一个 LogicFlow 实例只能声明一个 portal provider const LFReactPortalProvider Portal.getProvider() const ThemeContext React.createContext(light) // 组件内部可以正常使用 useContext const NodeComponent: FCReactNodeProps ({ node }) { const theme useContext(ThemeContext) const data node.getData() if (!data.properties) data.properties {} return ( div className{react-algo-node ${theme light ? light : dark}} img src{require(/public/didi.png)} alt滴滴出行 / span{data.properties.name as string}/span /div ) } // 业务页面中 // 1. 将 Provider 组件挂载到应用组件树并包裹在 ThemeContext.Provider 内部 // 2. 照常注册节点并添加 register({ type: custom-react-node, component: NodeComponent }, lf) lf.addNode({ id: react-node-1, type: custom-react-node, x: 80, y: 80, properties: { name: 今日出行, width: 120, height: 28 }, })在页面 JSX 中这样使用ThemeContext.Provider value{this.state.theme} LFReactPortalProvider / /ThemeContext.Provider当点击按钮切换theme时节点组件通过useContext(ThemeContext)拿到最新值从而实现了节点内容跟随外部 Context 状态实时变化。注意源码注释中的约束一个 LogicFlow 实例只能声明一个 portal provider。Portal 的底层实现Portal 机制位于 packages/react-node-registry/src/portal.tsPortal.getProvider()返回一个 Provider 组件挂载时通过useReducer维护{ id, portal }[]列表portal.ts渲染阶段ReactNodeView.renderReactComponent会先检查Portal.isActive()若 Portal 已激活则用createPortal(elem, container, model.id)创建 React Portal 并交给Portal.connect()存入 reducer节点 DOM 上保留占位容器否则回退到createRoot方案view.tsPortal 通过model.id唯一标识卸载时调用Portal.disconnect(id)移除portal.ts。由于 Portal 渲染的元素仍处于应用主 React 树中Context 自然可以穿透到节点组件内部这是它相比默认模式的核心优势。进阶标题栏与容器能力源码附带能力除了基础的组件渲染logicflow/react-node-registry还内置了标题栏容器能力源码可见于 packages/react-node-registry/src/components/Container.tsx 与 TitleBar.tsx。当properties._showTitle为true时Wrapper会把组件内容包进Container为其自动添加标题栏。支持的属性定义见 model.ts属性类型默认值说明_showTitlebooleanfalse是否显示标题栏_titlestring标题文字_iconstring无标题左侧图标_titleHeightnumber28标题栏高度_expandedbooleanfalse是否展开内容区折叠时仅显示标题栏style.titleColorstring#E5EEFC标题栏渐变底色开启标题模式时ReactNodeModel构造器会做若干约束设置最小宽高160 × 80、关闭文字编辑并注入「复制 / 删除」两个默认操作项通过setNodeActions见 model.ts。标题栏提供展开/收起切换与「⋯」更多操作菜单触发方式可通过properties.titleTrigger设置为click默认或hover见 TitleBar.tsx。开发者也可以用model.setNodeActions(actions)自定义操作项或通过_titleActions传入。小结本文基于官方文档与仓库源码完整梳理了logicflow/react-node-registry的使用路径注册register({ type, component, effect }, lf)将 React 组件注册为节点类型组件通过ReactNodeProps拿到node与graph刷新属性变化经NODE_PROPERTIES_CHANGE事件驱动Wrapper重渲染effect可用于过滤不关心的属性Context需要访问外部 Context 时启用Portal.getProvider()节点内容以 Portal 方式挂回应用主渲染树进阶_showTitle等属性可开启标题栏容器内置展开/折叠与操作菜单。对于想进一步探索的读者可在仓库中查看以下资源完整示例代码见 sites/docs/src/tutorial/advanced/react/index.tsx 与 Portal.tsx核心实现见 packages/react-node-registry/src 目录下的registry.ts、view.ts、model.ts、wrapper.tsx与portal.ts。该包对应的 Vue 版本为logicflow/vue-node-registry实现思路一致可对照参考 packages/vue-node-registry。【免费下载链接】LogicFlowA flow chart editing framework focus on business customization. 专注于业务自定义的流程图编辑框架支持实现脑图、ER图、UML、工作流等各种图编辑场景。项目地址: https://gitcode.com/GitHub_Trending/lo/LogicFlow创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号