ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

lowcode-engine:ReactRenderer 数据源实战 —— 从 Schema 配置到 DataHelper 请求引擎的完整解析

2026/9/14 13:29:51 拓冰建站 浏览量
lowcode-engine:ReactRenderer 数据源实战 —— 从 Schema 配置到 DataHelper 请求引擎的完整解析 lowcode-engineReactRenderer 数据源实战 —— 从 Schema 配置到 DataHelper 请求引擎的完整解析【免费下载链接】lowcode-engineAn enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系项目地址: https://gitcode.com/GitHub_Trending/lo/lowcode-engine本篇围绕 lowcode-engine 中packages/react-renderer的数据源 Demo 展开讲解如何用ReactRenderer组件加载一份声明了dataSource的页面 Schema理解isInit、type、options、dataHandler等数据源配置项在渲染引擎中的实际含义读完并对照仓库源码后你能掌握低代码页面从声明数据接口到表达式取数渲染的完整链路以及DataHelper/doRequest底层的请求调度与状态管理机制。一、Demo 场景用 ReactRenderer 渲染一个带数据源的待办列表packages/react-renderer是面向 React 运行时的渲染器包其 README 之外demo目录提供了几组可直接运行的示例页面compose / dataSource / i18n / list / table本文聚焦数据源示例。Demo 的入口代码位于 dataSource.mdimport React, { PureComponent } from react; import ReactDOM from react-dom; import ReactRenderer from alilc/lowcode-react-renderer; import schema from ./schemas/dataSource; import components from ./config/components/index; import utils from ./config/utils; import constants from ./config/constants; class Demo extends PureComponent { static displayName renderer-demo; render() { return ( div classNamedemo ReactRenderer key{schema.fileName} schema{schema} components{components} appHelper{{ utils, constants }} / /div ); } } ReactDOM.render(( Demo / ), mountNode);这段代码展示了ReactRenderer的四个关键入参schema页面 Schema本例即demo/schemas/dataSource.js其中声明了组件树与数据源components组件物料库config/components/index.js 中同时提供了自定义组件Div、Text、A、Image和整套alifd/nextFusion 组件Switch、Button、Table等渲染器通过componentName从中匹配组件appHelper注入到页面运行时上下文中的辅助对象config/utils.js 注入了Message、moment以及自定义方法test(msg)页面内的 JS 表达式可通过this.utils访问constants同理key{schema.fileName}切换 Schema 时用key强制重建渲染器实例。1.1 页面 Schema声明数据源与取数表达式对应的页面 Schema 在 demo/schemas/dataSource.js完整结构如下export default { componentName: Page, fileName: dataSource, props: {}, children: [{ componentName: Div, props: {}, children: [{ componentName: Text, props: { text: {{this.item.title}}, }, }, { componentName: Switch, props: { checkedChildren: 开, unCheckedChildren: 关, checked: {{this.item.done}}, }, }], loop: {{this.dataSourceMap.todos.data}}, }], dataSource: { list: [{ id: todos, isInit: true, type: jsonp, options: { method: GET, uri: https://mocks.alibaba-inc.com/mock/D8iUX7zB/todo_getAll, }, dataHandler: function dataHandler(data) { return data.data; }, }], }, };这份 Schema 浓缩了数据源用法的三个要点页面级数据源声明dataSource.list数组描述页面要拉取的接口。每个数据源项的核心字段为id数据源唯一标识运行时挂载到this.dataSourceMap.todosisInit是否为true严格布尔值时页面初始化即自动请求。源码中对这一点有明确注释——按规范isInit必须是 boolean 的true才会生效type请求类型。渲染器核心内置支持fetch与jsonp两种示例选用jsonpoptionsuri请求地址、method默认GET、params、headers、timeout等dataHandler对返回数据做转换的函数这里return data.data表示取出响应体的data字段作为数据源值。loop 循环渲染Div上的loop: {{this.dataSourceMap.todos.data}}表示遍历数据源返回的待办数组数组中的每一项注入到作用域变量item子节点的text、checked等属性用{{this.item.title}}、{{this.item.done}}表达式绑定——这正是数据源 表达式驱动的声明式渲染。组件树与数据解耦Schema 只描述取哪个数、用在哪请求的发起、缓存与更新全部由渲染器内部的数据源引擎完成。二、源码剖析ReactRenderer 如何把 React 运行时接入渲染核心alilc/lowcode-react-renderer本身并不包含渲染逻辑它在 packages/react-renderer/src/index.ts 中做了两件关键的事通过adapter.setRuntime注入 React 运行时Component、PureComponent、createElement、forwardRef、ReactDOM.findDOMNode等并把ReactDOM.findDOMNode挂到全局通过adapter.setRenderers注册五类渲染器PageRenderer、ComponentRenderer、BlockRenderer、AddonRenderer、TempRenderer外加一个DivRenderer。这些工厂均来自alilc/lowcode-renderer-core包。ReactRenderer组件最终由rendererFactory()产出见 packages/renderer-core/src/renderer/renderer.tsx。入口类在render()中做了三件事校验 Schema 根节点必须为Page/Block/Component之一否则提示模型结构异常将appHelper、合并后的组件库与引擎实例一起通过AppContext.Provider下发再用 Fusion 的ConfigProvider包裹adapter.setConfigProvider(ConfigProvider)最终按componentName从物料库中取出组件渲染提供了faultComponent/notFoundComponent容错机制组件渲染异常时不会整体崩溃。也就是说Demo 里传入的components物料与内置的PageRenderer等渲染器组件合并后{ ...RENDERER_COMPS, ...components }Page会命中PageRendererDiv、Text、Switch则命中物料库中的同名组件。三、DataHelper数据源调度、状态与 dataHandler 的执行细节数据源的运行逻辑集中在 packages/renderer-core/src/utils/data-helper.ts 的DataHelper类结合 Demo 中todos数据源可以逐环节对照3.1 dataSourceMap 的生成与初始化请求构造函数接收页面组件实例this.host、dataSource配置、appHelper和表达式解析器parser把config.list通过transformArrayToMap(..., id)建成ajaxMap并调用generateDataSourceMap()生成dataSourceMap。每个数据源项初始化为res[item.id] { status: init, // DS_STATUS.INIT load: (...args) this.getDataSource(item.id, ...args), };getInitDataSourseConfigs()遍历list只有item.isInit true的项才置为loading并纳入初始化请求集合asyncDataHandler用Promise.all并发发起所有初始化请求每项完成时调用updateDataSourceMap(id, data, error)写回data、error与statusloaded/error。数据源状态机共四种init、loading、loaded、error见DS_STATUS常量。3.2 dataHandler 的两种形态handleData中可以看到dataHandler支持两种写法JSFunction 对象isJSFunction(dataHandler)为真时取其value字符串经transformStringToFunction还原为函数——这对应 Schema 中以字符串/JSFunction 形态存储的处理函数出码与编辑态的通用形态普通函数Demo 的dataSource.js是直接写function dataHandler(data) { return data.data; }被识别为函数后直接执行。函数执行时的this绑定为渲染器组件实例dataHandlerFun.call(this.host, data, error)因此在dataHandler内可以访问页面的state、props等上下文执行出错时仅打印带id的错误日志不会打断其他数据源的加载。3.3 手动触发与参数合并getDataSourcedataSourceMap.id.load(params?, otherOptions?)支持运行时手动重新请求内部getDataSource的关键行为回调形态兼容第二个参数若是函数则被当作callbackparams合并策略当配置或调用方任一侧为数组时不做合并整体替换否则浅合并{ ...options.params, ...params }headers恒为浅合并请求结果既写入dataSourceMap触发视图更新也通过 Promise 与callbackFn双通道返回失败时status置为error并把error存到dataSourceMap[id].error。另外updateConfig支持热更新数据源配置移除项会同步从dataSourceMap中删除新增项按init状态挂载已存在项保留原状态——这是编辑态修改数据源配置后无需重建页面即可生效的机制。四、请求层fetch 与 jsonp 的内置实现doRequest(type, options)是数据源类型到 HTTP 实现的映射入口见 contenteditable="false">【免费下载链接】lowcode-engineAn enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系项目地址: https://gitcode.com/GitHub_Trending/lo/lowcode-engine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考