Next.js Link导航时Feefo产品评论组件不更新问题求助
问题:Next.js 页面路由下 Feefo 产品评论组件导航后不更新
使用 Next.js ^12.3.0 + React ^17.0.2(页面路由)集成 Feefo Product Reviews 组件时遇到以下问题:
- 初始产品页能正常显示对应SKU的评论
- 通过 Next.js
Link组件导航到其他产品页时,评论组件仍显示上一个产品的内容,不会更新为当前产品SKU对应的评论 - 使用原生
<a>标签硬刷新可以解决,但希望保留 Next.js 客户端导航的性能优势
当前集成代码:
- 引入Feefo脚本:
<Script type="text/javascript" src="https://api.feefo.com/api/javascript/user" async />
- 渲染评论组件:
<div className="feefo-product-stars-widget mb-1 review-stars" data-product-sku={product.sku} data-parent-product-sku={product.sku} />
核心原因:Next.js 客户端导航不会触发页面硬重载,Feefo的初始化脚本仅在首次加载时执行,新路由下的组件无法自动触发重新初始化。
解决方案
1. 监听路由变化,手动触发Feefo重新渲染
Feefo全局对象(window.feefo)提供了render()方法,可在路由切换完成后调用它更新组件。在产品页面组件中添加如下逻辑:
import { useRouter } from 'next/router'; import { useEffect, useRef } from 'react'; const ProductPage = ({ product }) => { const router = useRouter(); const skuRef = useRef(product.sku); useEffect(() => { const handleRouteChange = () => { // 仅当SKU发生变化时触发更新 if (skuRef.current !== product.sku) { skuRef.current = product.sku; window.feefo?.widgets?.render(); } }; router.events.on('routeChangeComplete', handleRouteChange); // 组件卸载时移除监听 return () => router.events.off('routeChangeComplete', handleRouteChange); }, [router, product.sku]); return ( <> <h1>{product.title}</h1> <div className="feefo-product-stars-widget mb-1 review-stars" data-product-sku={product.sku} data-parent-product-sku={product.sku} /> {/* 其他产品内容 */} </> ); }; export default ProductPage;
2. 确保脚本加载完成后再执行渲染(兼容极端场景)
如果遇到Feefo脚本未加载完成就触发渲染的情况,可以添加脚本加载监听,确保初始化时机正确:
useEffect(() => { const initFeefo = () => window.feefo?.widgets?.render(); // 检查脚本是否已加载 const existingScript = document.querySelector('script[src="https://api.feefo.com/api/javascript/user"]'); if (existingScript) { initFeefo(); } else { // 动态加载脚本作为兜底方案 const script = document.createElement('script'); script.src = 'https://api.feefo.com/api/javascript/user'; script.async = true; script.onload = initFeefo; document.body.appendChild(script); } // 路由切换时重新渲染 const handleRouteChange = () => initFeefo(); router.events.on('routeChangeComplete', handleRouteChange); return () => router.events.off('routeChangeComplete', handleRouteChange); }, [router, product.sku]);
3. 清理旧DOM容器(解决顽固缓存问题)
如果Feefo存在DOM缓存导致不更新的情况,可以在SKU变化时先移除旧组件容器,再重新创建并渲染:
useEffect(() => { const targetContainer = document.querySelector('.feefo-product-stars-widget'); if (targetContainer && targetContainer.dataset.productSku !== product.sku) { // 移除旧容器 targetContainer.remove(); // 创建新容器并插入到指定位置 const newContainer = document.createElement('div'); newContainer.className = 'feefo-product-stars-widget mb-1 review-stars'; newContainer.dataset.productSku = product.sku; newContainer.dataset.parentProductSku = product.sku; // 假设插入到产品标题的下一个位置,可根据实际DOM结构调整 document.querySelector('h1').after(newContainer); // 触发渲染 window.feefo?.widgets?.render(); } }, [product.sku]);
内容的提问来源于stack exchange,提问作者mnn
相关产品推荐
相关产品推荐

