无需jQuery,如何在React页面嵌入HTML/script片段及Airbnb预览组件?
嘿,这个问题我刚好踩过坑!用Create React App搭建的项目里嵌入第三方组件(比如Airbnb的预览组件),完全不用jQuery,下面我给你拆解两种场景的具体做法,都是实际项目里验证过的:
一、嵌入Airbnb预览组件(无需jQuery)
Airbnb提供的预览组件一般是「一个容器div + 一段远程script」的组合,我们可以利用React的钩子来动态加载脚本并初始化组件,步骤如下:
1. 核心实现(函数组件版)
import { useRef, useEffect } from 'react'; function AirbnbListingPreview() { // 用来获取挂载组件的容器元素 const airbnbContainer = useRef(null); useEffect(() => { // 先检查脚本是否已经加载过,避免重复请求 const existingScript = document.querySelector('script[src="https://airbnb.example.com/embed-script.js"]'); if (existingScript) { initAirbnbWidget(); return; } // 动态创建script标签 const script = document.createElement('script'); script.src = 'https://airbnb.example.com/embed-script.js'; // 替换成Airbnb给你的实际脚本地址 script.async = true; // 脚本加载完成后执行初始化 script.onload = initAirbnbWidget; // 将脚本添加到页面body中 document.body.appendChild(script); // 组件卸载时清理脚本(可选,根据需求决定是否保留) return () => { if (!existingScript) { document.body.removeChild(script); } }; }, []); // 初始化Airbnb预览组件的函数 const initAirbnbWidget = () => { if (airbnbContainer.current) { // 这里调用Airbnb脚本暴露的全局初始化方法 // 具体方法名和参数请参考Airbnb提供的文档,比如下面是示例 window.renderAirbnbEmbed({ container: airbnbContainer.current, listingId: 'your-listing-id-here', // 替换成你的房源ID showReviews: true, width: '100%' }); } }; return ( <div ref={airbnbContainer} className="airbnb-preview" style={{ minHeight: '300px' }} // 给个默认高度避免布局跳动 /> ); } export default AirbnbListingPreview;
关键说明:
- 用
useRef获取容器元素,确保脚本能找到挂载的DOM节点 useEffect在组件首次挂载时加载脚本,依赖项设为空数组保证只执行一次- 脚本加载完成后调用Airbnb的全局初始化方法,把容器元素传进去即可,全程用原生JS,完全不需要jQuery
二、在React中嵌入通用HTML/Script代码片段
如果是其他第三方的HTML/script片段,分两种情况处理:
1. 静态HTML片段(无动态脚本)
如果只是纯静态HTML内容,可以用React提供的dangerouslySetInnerHTML属性插入,但一定要确保内容是可信的,避免XSS风险:
function StaticThirdPartyContent() { // 替换成你要嵌入的静态HTML代码 const htmlSnippet = ` <div class="third-party-card"> <h3>第三方静态内容</h3> <p>这是一段不需要动态脚本的HTML片段</p> <img src="https://example.com/image.jpg" alt="示例图片"> </div> `; return <div dangerouslySetInnerHTML={{ __html: htmlSnippet }} />; }
2. 含动态脚本的片段
和Airbnb组件的思路一致,核心是动态创建脚本并控制加载时机,比如嵌入某个统计脚本或动态渲染组件:
import { useRef, useEffect } from 'react'; function DynamicScriptComponent() { const containerRef = useRef(null); useEffect(() => { // 创建脚本标签 const script = document.createElement('script'); script.type = 'text/javascript'; // 如果是inline脚本,直接写入内容(注意转义引号) script.textContent = ` function renderDynamicContent() { const container = document.getElementById('dynamic-content-container'); container.innerHTML = '<p>这是动态脚本渲染的内容</p>'; } renderDynamicContent(); `; // 将脚本添加到容器中 containerRef.current.appendChild(script); // 组件卸载时清理脚本 return () => { containerRef.current.removeChild(script); }; }, []); return <div ref={containerRef} id="dynamic-content-container"></div>; }
3. 封装成自定义Hook(提高复用性)
如果经常需要加载第三方脚本,可以封装一个通用Hook,减少重复代码:
import { useEffect } from 'react'; // 自定义Hook:加载远程脚本 function useLoadRemoteScript(src, onScriptLoaded) { useEffect(() => { const existingScript = document.querySelector(`script[src="${src}"]`); if (existingScript) { onScriptLoaded?.(); return; } const script = document.createElement('script'); script.src = src; script.async = true; script.onload = () => onScriptLoaded?.(); script.onerror = () => console.error(`加载脚本失败:${src}`); document.body.appendChild(script); return () => { if (!existingScript) { document.body.removeChild(script); } }; }, [src, onScriptLoaded]); } // 使用示例 function AirbnbPreview() { const containerRef = useRef(null); useLoadRemoteScript( 'https://airbnb.example.com/embed-script.js', () => { window.renderAirbnbEmbed({ container: containerRef.current, listingId: 'your-listing-id' }); } ); return <div ref={containerRef}></div>; }
额外注意事项:
- 脚本加载失败时,可以通过
script.onerror添加错误处理逻辑,避免静默失败 - 不要直接在JSX中写
<script>标签,React会自动过滤这类标签,必须动态创建 - 如果第三方脚本依赖特定的全局变量,要确保脚本加载时这些变量已经存在
内容的提问来源于stack exchange,提问作者xiaoju
相关产品推荐
相关产品推荐

