Syncfusion Dashboard Layout如何使用带props的React组件作为面板
Syncfusion Dashboard Layout 嵌入响应式React组件解决方案
Syncfusion Dashboard Layout 组件默认的content配置项仅支持传入静态字符串、原生HTML节点,内部不会走React虚拟DOM渲染流程,因此直接传入React组件时无法触发props更新、重渲染等响应式逻辑,可通过以下两种方案实现动态交互渲染:
方案1:利用面板渲染回调手动挂载React组件
组件渲染完成后会触发
created事件,可在事件回调中获取每个面板的内容容器DOM节点,通过React官方提供的挂载方法将自定义组件渲染到对应容器中,组件的状态、props更新完全遵循React原生逻辑。
示例代码:import { useEffect, useRef, useState } from 'react'; import { createRoot } from 'react-dom/client'; import { DashboardLayoutComponent, PanelsDirective, PanelDirective } from '@syncfusion/ej2-react-layouts'; import CustomDynamicWidget from './CustomDynamicWidget'; export default function CustomDashboard() { const dashboardIns = useRef(null); const panelRootMap = useRef(new Map()); const [widgetProps, setWidgetProps] = useState({ count: 0 }); const renderPanelContent = () => { const contentContainers = dashboardIns.current.element.querySelectorAll('.e-panel-content'); contentContainers.forEach((container, idx) => { if (panelRootMap.current.has(container)) return; const root = createRoot(container); root.render(<CustomDynamicWidget {...widgetProps} />); panelRootMap.current.set(container, root); }); }; // props变化时手动更新已挂载的组件 useEffect(() => { panelRootMap.current.forEach((root) => { root.render(<CustomDynamicWidget {...widgetProps} />); }); }, [widgetProps]); // 组件卸载时清理挂载实例,避免内存泄漏 useEffect(() => { return () => { panelRootMap.current.forEach(root => root.unmount()); panelRootMap.current.clear(); }; }, []); return ( <div> <button onClick={() => setWidgetProps(prev => ({count: prev.count + 1}))}> 触发组件更新 </button> <DashboardLayoutComponent ref={dashboardIns} created={renderPanelContent} cellSpacing={[10, 10]} columns={4} > <PanelsDirective> <PanelDirective sizeX={2} sizeY={2} row={0} col={0} content="" /> <PanelDirective sizeX={2} sizeY={2} row={0} col={2} content="" /> </PanelsDirective> </DashboardLayoutComponent> </div> ); }方案2:使用React Portal渲染面板内容
如果希望完全遵循React的组件树逻辑、共享上层Context,可以在拿到面板内容容器DOM后,通过
ReactDOM.createPortal将自定义组件渲染到对应容器中。这种写法不需要手动管理React根实例,组件的更新、卸载逻辑会由React自动处理,代码更贴合常规React开发模式。
注意如果面板拖拽、尺寸调整后容器DOM被重建,需要更新Portal的目标容器节点,避免渲染位置异常。
注意事项
- 不要直接将React JSX元素传入面板的
content属性,组件内部会直接将值作为原生DOM插入,不会解析React的虚拟DOM结构,无法绑定响应式更新逻辑 - 如果开启了面板拖拽、动态增删面板功能,需要在面板变更事件触发后重新检查容器DOM,补做组件挂载逻辑
- 动态移除面板时需要同步卸载对应容器上挂载的React组件,避免内存泄漏
内容的提问来源于stack exchange,提问作者Ognjen Popovic
相关产品推荐
相关产品推荐

