如何将seatchart.js原生JS脚本正确集成到React应用组件中
核心实现逻辑
非React生态的原生JS库集成到React组件时,必须满足两个前提:
- 库的构造函数/方法在调用前已完成加载,可被访问
- 库要挂载的DOM节点已完成渲染,存在于当前页面DOM树中
具体实现步骤
1. 脚本引入配置
将seatchart.js源码文件放到项目public目录下,修改public/index.html的body内容,将脚本引入放到root节点之后,避免阻塞页面渲染,同时保证脚本加载后全局可访问:
<body> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"></div> <script type="text/javascript" src="/seatchart.js"></script> </body>
2. 组件代码实现
使用useEffect钩子保证初始化操作在DOM挂载完成后执行,用useRef存储实例避免重复初始化,组件卸载时自动清理相关DOM避免内存泄漏:
import { useEffect, useRef } from 'react' export default function Ticket () { const seatchartRef = useRef(null) const options = { map: { id: 'map-container', rows: 9, columns: 9, reserved: { seats: [1, 2, 3, 5, 6, 7, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21], }, disabled: { seats: [0, 8], rows: [4], columns: [4] } }, types: [ { type: "regular", backgroundColor: "#006c80", price: 10, selected: [23, 24] }, { type: "reduced", backgroundColor: "#287233", price: 7.5, selected: [25, 26] } ], cart: { id: 'cart-container', width: 280, height: 250, currency: '£', }, legend: { id: 'legend-container', }, assets: { path: "/", } }; useEffect(() => { if (seatchartRef.current) return if (window.Seatchart && document.getElementById(options.map.id)) { seatchartRef.current = new window.Seatchart(options) } return () => { if (seatchartRef.current) { document.getElementById(options.map.id).innerHTML = '' document.getElementById(options.cart.id).innerHTML = '' document.getElementById(options.legend.id).innerHTML = '' seatchartRef.current = null } } }, []) return ( <div> <div id="map-container"></div> <div id="legend-container"></div> <div id="cart-container"></div> </div> ) }
过往尝试的错误原因
- 直接在组件函数主体执行初始化操作时,组件返回的DOM节点还未渲染到页面,无法找到对应容器触发appendChild报错
- 在index.html中提前执行初始化逻辑时,React组件还未挂载,同样不存在对应的DOM节点
- localStorage仅支持存储字符串格式内容,无法存储JS对象实例,序列化后会丢失所有属性和方法
- 资源路径配置错误,React项目public目录下的静态资源访问根路径为
/,无需添加../../public前缀
内容的提问来源于stack exchange,提问作者Franco-yvr
相关产品推荐
相关产品推荐

