如何在Webpack与Babel环境下替代jQuery的$(document).ready()实现React组件挂载?
不用jQuery,更优雅地在PHP生成的页面挂载React组件
嘿,完全理解你为啥觉得依赖jQuery来处理DOM就绪再挂载React有点冗余——其实咱们完全可以用原生浏览器API或者更贴合React生态的方式来实现,既去掉了不必要的库依赖,代码也更清爽。下面给你几个靠谱的方案:
方案一:用原生DOMContentLoaded替代jQuery
jQuery的$(function(){})本质上就是封装了浏览器的DOMContentLoaded事件,咱们直接用原生API实现同样的逻辑,完全不需要引入jQuery:
// 创建一个DOM就绪的Promise,只初始化一次 const documentReadyPromise = new Promise(resolve => { // 如果DOM已经处于就绪状态(比如脚本在body末尾加载),直接resolve if (document.readyState === "complete" || document.readyState === "interactive") { resolve(); } else { // 否则监听DOMContentLoaded事件 document.addEventListener("DOMContentLoaded", resolve); } }); export function getDocumentReadyPromise() { return documentReadyPromise; } export function getReactReadyPromise() { return Promise.all([ getDocumentReadyPromise() // 这里可以添加其他需要等待的异步依赖,比如某个接口请求、资源加载 ]); }
使用方式和你原来的几乎一样,但已经摆脱了jQuery:
getReactReadyPromise().then(() => { ReactDOM.render( <MyComponent />, document.getElementById('my-component-mount-point') ); });
方案二:只等待挂载节点就绪,不用等整个DOM
如果你的PHP页面里,React挂载节点#my-component-mount-point是直接输出在HTML里的,有时候不需要等整个DOM都加载完成,只需要等这个节点存在就行。咱们可以写一个专门等待元素的工具函数:
function waitForMountPoint(selector) { return new Promise(resolve => { function checkElement() { const element = document.getElementById(selector); if (element) { resolve(element); } else { // 用requestIdleCallback来避免阻塞主线程,比setTimeout更高效 requestIdleCallback(checkElement); } } checkElement(); }); }
使用的时候更直接,拿到节点就挂载:
waitForMountPoint('my-component-mount-point').then(mountNode => { ReactDOM.render( <MyComponent />, mountNode ); });
方案三:结合React 18的现代API(推荐)
如果你已经升级到React 18,建议使用createRoot这个新API,搭配上面的等待逻辑,代码更符合React的最新规范:
import { createRoot } from 'react-dom/client'; waitForMountPoint('my-component-mount-point').then(mountNode => { const root = createRoot(mountNode); root.render(<MyComponent />); });
为什么这些方案更好?
- 减少打包体积:去掉jQuery依赖,能帮你的bundle瘦一圈
- 更原生可控:直接使用浏览器API,避免库封装带来的额外逻辑
- 更灵活:可以根据实际需求选择等待整个DOM,还是只等待挂载节点
- 贴合React生态:React 18的API能更好地支持后续的并发特性
内容的提问来源于stack exchange,提问作者Meglio
相关产品推荐
相关产品推荐

