使用react-router-dom路由至页面后如何正确刷新页面?
解决React路由跳转后Mindbody Widget不加载的问题
方案一:动态加载Mindbody脚本(推荐,无需页面刷新)
不用依赖页面刷新,在组件挂载时手动注入并执行Mindbody的脚本,路由跳转后就能直接加载:
import * as React from 'react'; import { Stack, Box, Typography, Modal, Backdrop } from '@mui/material'; import ButtonV2 from './ButtonV2'; import PurchaseWidget from './PurchaseWidget'; const style = { position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', width: 400, bgcolor: 'background.paper', boxShadow: 24, borderRadius: 3, transition: "5s ease-in-out" }; const PurchaseLanding = () => { const [show, setShow] = React.useState(true); const handleClose = () => setShow(false); React.useEffect(() => { // 检查是否已加载过脚本,避免重复注入 const existingScript = document.getElementById('mindbody-script'); if (existingScript) { initMindbodyWidget(); return; } // 创建新脚本标签 const script = document.createElement('script'); script.id = 'mindbody-script'; script.src = '替换为Mindbody提供的脚本URL'; // 比如官方widget脚本地址 script.async = true; // 脚本加载完成后初始化widget script.onload = () => { initMindbodyWidget(); }; document.head.appendChild(script); // 组件卸载时移除脚本(可选) return () => { script && document.head.removeChild(script); }; }, []); // 根据Mindbody文档实现widget初始化逻辑 const initMindbodyWidget = () => { if (window.Mindbody) { window.Mindbody.loadWidget({ // 填入你的widget配置参数 }); } }; return ( <div> <Modal open={show} onClose={handleClose} aria-labelledby="modal-modal-title" aria-describedby="modal-modal-description" disableAutoFocus="true" BackdropComponent={Backdrop} BackdropProps={{ timeout: 500, }}> <Box sx={style}> <div> <img style={{borderRadius: "10px 10px 0 0"}} src="https://res.cloudinary.com/djjb1vyjm/image/upload/v1660541084/1_uxhi8p.png" width="100%" alt="" /> </div> <Box p={2}> <Typography align="center" id="modal-modal-title" variant="h5" component="h2"> <span className='space-font-heavy'>Buy your [10-pack]</span> </Typography> <Stack pb={3} alignItems="center" justifyContent="center" direction="row" spacing={2}> <Typography px={1} align="center" id="modal-modal-description" sx={{ mt: 2 }}> <span className='space-font-light'>Once completed download the Mindbody app to add, update, and book your workouts!</span> </Typography> </Stack> <Stack direction="row" justifyContent="center" alignItems="center"> <ButtonV2 /> </Stack> </Box> </Box> </Modal> </div> ); } export default PurchaseLanding
方案二:控制页面刷新(仅首次进入路由时执行)
如果必须通过页面刷新加载脚本,用路由状态或本地存储标记,避免无限循环:
import * as React from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; import { Stack, Box, Typography, Modal, Backdrop } from '@mui/material'; import ButtonV2 from './ButtonV2'; import PurchaseWidget from './PurchaseWidget'; const style = { position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', width: 400, bgcolor: 'background.paper', boxShadow: 24, borderRadius: 3, transition: "5s ease-in-out" }; const PurchaseLanding = () => { const [show, setShow] = React.useState(true); const handleClose = () => setShow(false); const location = useLocation(); const navigate = useNavigate(); React.useEffect(() => { // 检查是否是首次进入该页面 const hasRefreshed = location.state?.hasRefreshed || localStorage.getItem('mb-refreshed'); if (!hasRefreshed) { // 标记已刷新,避免循环 localStorage.setItem('mb-refreshed', 'true'); // 刷新页面并传递状态标记 navigate(location.pathname, { state: { hasRefreshed: true }, replace: true }); window.location.reload(); } else { // 刷新完成后清除标记 localStorage.removeItem('mb-refreshed'); } }, [location, navigate]); return ( <div> <Modal open={show} onClose={handleClose} aria-labelledby="modal-modal-title" aria-describedby="modal-modal-description" disableAutoFocus="true" BackdropComponent={Backdrop} BackdropProps={{ timeout: 500, }}> <Box sx={style}> <div> <img style={{borderRadius: "10px 10px 0 0"}} src="https://res.cloudinary.com/djjb1vyjm/image/upload/v1660541084/1_uxhi8p.png" width="100%" alt="" /> </div> <Box p={2}> <Typography align="center" id="modal-modal-title" variant="h5" component="h2"> <span className='space-font-heavy'>Buy your [10-pack]</span> </Typography> <Stack pb={3} alignItems="center" justifyContent="center" direction="row" spacing={2}> <Typography px={1} align="center" id="modal-modal-description" sx={{ mt: 2 }}> <span className='space-font-light'>Once completed download the Mindbody app to add, update, and book your workouts!</span> </Typography> </Stack> <Stack direction="row" justifyContent="center" alignItems="center"> <ButtonV2 /> </Stack> </Box> </Box> </Modal> </div> ); } export default PurchaseLanding
注意事项
- 方案一需要对照Mindbody官方文档,替换
initMindbodyWidget里的初始化逻辑。 - 方案二会导致页面短暂闪烁,体验不如方案一,优先推荐方案一。
内容的提问来源于stack exchange,提问作者frankieseattle
相关产品推荐
相关产品推荐

