路由导航时保持进度条状态不重置的技术求助
解决路由导航时进度条重置的问题
你的问题核心是:路由切换时,ProgressBarTimer组件会被卸载再重新挂载,导致内部的progress状态重置为0,同时新的定时器又从0开始计数。下面给你几个可行的解决思路:
1. 将进度状态移到全局Context中
既然你已经在用DepositContext,可以把progress状态和更新逻辑直接放到Context里,让状态脱离组件生命周期:
修改DepositContext:
// DepositContext.js import { createContext, useState, useEffect } from 'react'; const DepositContext = createContext(); export const DepositProvider = ({ children, delayCount }) => { const [progress, setProgress] = useState(0); useEffect(() => { const interval = setInterval(() => { setProgress(prev => prev === 100 ? 0 : prev + 1); }, delayCount); return () => clearInterval(interval); }, [delayCount]); return ( <DepositContext.Provider value={{ delayCount, progress }}> {children} </DepositContext.Provider> ); }; export default DepositContext;
修改ProgressBarTimer组件:
import { useContext } from "react"; import LinearProgress from '@mui/material/LinearProgress'; import DepositContext from "../Deposit/PaymentWindows/DepositContext"; import { styled } from "@mui/material"; const ProgressBarTimer = () => { const { progress } = useContext(DepositContext); // 这里可以保留你的样式代码 const StyledLinearProgress = styled(LinearProgress)(({ theme }) => ({ // 你的样式逻辑 })); return <StyledLinearProgress variant="determinate" value={progress} />; };
这样不管路由怎么切换,只要DepositProvider在路由组件的外层(比如App.js里),状态就会持续保留,定时器也不会中断。
2. 把进度条组件放在路由外层
如果不需要全局共享状态,直接把ProgressBarTimer放在路由组件的外面(比如App.js的根节点),这样路由切换时组件不会卸载,状态和定时器都能保持:
// App.js import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import ProgressBarTimer from './components/ProgressBarTimer'; import Page1 from './pages/Page1'; import Page2 from './pages/Page2'; function App() { return ( <Router> <ProgressBarTimer /> {/* 放在路由外面,不会随页面卸载 */} <Routes> <Route path="/page1" element={<Page1 />} /> <Route path="/page2" element={<Page2 />} /> </Routes> </Router> ); }
3. 修复localStorage的使用方式
如果你之前用localStorage没成功,可能是没正确初始化和同步状态。试试这样修改:
const ProgressBarTimer = () => { const { delayCount } = useContext(DepositContext); // 初始化时从localStorage读取进度 const [progress, setProgress] = useState(() => { const saved = localStorage.getItem('progress'); return saved ? parseInt(saved) : 0; }); useEffect(() => { const interval = setInterval(() => { setProgress(prev => { const newProgress = prev === 100 ? 0 : prev + 1; // 更新状态的同时同步到localStorage localStorage.setItem('progress', newProgress); return newProgress; }); }, delayCount); return () => clearInterval(interval); }, [delayCount]); // 渲染进度条... };
这种方式适合不需要全局共享,但需要页面刷新后也能保留进度的场景,路由切换时组件卸载再挂载会读取localStorage的最新值,不会从0开始。
内容的提问来源于stack exchange,提问作者Mahmoud Galal Ali
相关产品推荐
相关产品推荐

