如何在原生JavaScript项目中使用React Material UI组件
问题描述
改造需求如下:
- 接手原生JavaScript项目,需要对现有应用做部分修改
- 在不新建独立React应用、仅基于现有原生JS项目迭代的约束下,接入React组件能力
- 将应用内所有按钮替换为React组件(可选择Material UI的按钮组件实现),同时完成所有卡片、头部组件的对应替换
现有原生项目示例代码如下:
document.getElementById('container').innerHTML= `<div> <div id = 'button'></div> </div>` document.getElementById('button').innerHTML= `<button>click me</button>`;
<button>hello</button> <div id = 'container'></div>
实现方案
不需要重构现有项目结构、也不需要搭建React工程化环境,直接在现有项目基础上增量接入即可,步骤如下:
1. 引入基础依赖
在项目入口HTML文件中按顺序引入React、ReactDOM、Material UI、Babel Standalone的生产版本资源,无需额外配置构建工具即可直接运行。如果对页面性能有要求,生产环境可以将JSX代码预编译为普通JS,去掉Babel Standalone依赖。
2. 编写通用替换逻辑
写一个通用的DOM替换方法,在原有原生JS逻辑执行完成、DOM渲染完毕后,找到目标原生节点替换为挂载React组件的容器,再将对应React组件渲染到容器中即可,不需要改动原有业务逻辑。
针对给出的示例代码,改造后的完整逻辑如下:
<!-- 原有HTML结构保持不变 --> <button>hello</button> <div id="container"></div> <!-- 新增React组件替换逻辑,脚本类型标记为text/babel供浏览器端Babel解析 --> <script type="text/babel"> // 从Material UI全局对象中解构需要用到的组件 const { Button, Card, AppBar, Toolbar, Typography } = MaterialUI; /** * 通用DOM替换为React组件方法 * @param {string} selector 原生DOM选择器 * @param {React.ReactElement} reactElement 要渲染的React组件 */ function replaceNodeWithReact(selector, reactElement) { const targetNodes = document.querySelectorAll(selector); targetNodes.forEach(node => { const mountContainer = document.createElement('div'); node.replaceWith(mountContainer); ReactDOM.createRoot(mountContainer).render(reactElement); }) } // 等页面所有资源、原有DOM逻辑执行完成后执行替换 window.addEventListener('load', () => { // 原有原生JS逻辑完全保留,不需要修改 document.getElementById('container').innerHTML = `<div> <div id = 'button'></div> </div>` document.getElementById('button').innerHTML = `<button>click me</button>`; // 替换所有原生按钮为Material UI按钮,可根据需求传入variant、color、事件回调等属性 replaceNodeWithReact('button', <Button variant="contained" color="primary" onClick={() => console.log('React按钮点击事件触发')} > 按钮 </Button> ); // 后续替换卡片、头部组件逻辑和按钮一致,传入对应选择器和组件即可 // 示例:替换头部 // replaceNodeWithReact('.app-header', // <AppBar position="static"> // <Toolbar> // <Typography variant="h6">应用头部</Typography> // </Toolbar> // </AppBar> // ) // 示例:替换卡片 // replaceNodeWithReact('.info-card', <Card>卡片内容区域</Card>) }) </script>
适配说明
- 如果项目中存在动态渲染的按钮、卡片、头部组件,只需要在动态DOM插入页面的逻辑执行完成后,再调用
replaceNodeWithReact方法执行对应替换即可,不需要改动原有动态渲染逻辑 - React组件的props传递、事件绑定、样式配置和常规React开发完全一致,直接在传入的组件上配置即可
- 如果需要做更精细的属性映射(比如把原生按钮的
onclick事件同步到React按钮上、把原生class对应的样式同步到React组件),可以在replaceNodeWithReact方法里读取原生节点的属性,再透传给React组件即可
内容的提问来源于stack exchange,提问作者Shanu Singh
相关产品推荐
相关产品推荐

