【发布时间】:2022-06-10 23:14:06
【问题描述】:
我有一个计时器组件,即使在 react-router 路由 /settings 时它也应该继续运行,但它会重新渲染导致状态丢失。
Timer.tsx
import React, { useEffect, useRef, useState } from 'react';
import { CircularProgressbarWithChildren } from 'react-circular-progressbar';
import { BsPlayFill, BsPauseFill } from 'react-icons/bs';
import { useSelector } from 'react-redux';
import { convertToMin } from 'renderer/utils/time';
const Timer = () => {
const config = useSelector((state) => state.timer);
const defaultSeconds = config.workTime;
const defaultBreakSeconds = config.breakTime;
const [time, setTime] = useState({});
const timer = useRef(0);
const [paused, setPaused] = useState(true);
const [mode, setMode] = useState('focus');
const seconds = useRef(defaultSeconds);
function countDown() {
seconds.current--;
setTime(convertToMin(seconds.current));
if (seconds.current <= 0) {
clearInterval(timer.current);
restartTimer();
}
}
function restartTimer() {
if (mode === 'focus') {
var sec = defaultBreakSeconds;
setMode('break');
} else {
var sec = defaultSeconds;
setMode('focus');
}
timer.current = 0;
seconds.current = sec;
setTime(convertToMin(sec));
setPaused(true);
}
function startTimer() {
if (seconds.current > 0 && timer.current === 0) {
timer.current = setInterval(() => countDown(), 1000);
setPaused(false);
}
}
function getProgress(sec) {
return Math.floor((seconds.current / sec) * 100);
}
function pauseTimer() {
clearInterval(timer.current);
timer.current = 0;
setPaused(true);
}
useEffect(() => {
let t = convertToMin(defaultSeconds);
setTime(t);
}, []);
return (
<div className="timer-container">
<div className="progressbar">
<CircularProgressbarWithChildren
value={
mode === 'focus'
? getProgress(defaultSeconds)
: getProgress(defaultBreakSeconds)
}
text={`${time.min}:${time.sec}`}
styles={{
trail: { strokeWidth: 1, stroke: '#424656' },
path: {
strokeWidth: 4,
stroke: mode === 'break' ? '#3cc08e' : '#00aefc',
},
text: {
fill: '#00aefc',
},
}}
>
<div className="progress-text">{mode}</div>
</CircularProgressbarWithChildren>
</div>
<div className="action-buttons">
<button type="button">
{paused ? (
<BsPlayFill color="#f0fbff" size={30} onClick={startTimer} />
) : (
<BsPauseFill color="#f0fbff" size={30} onClick={pauseTimer} />
)}
</button>
</div>
</div>
);
};
export default Timer;
App.tsx
export default function App() {
return (
<>
<Provider store={store}>
<Router>
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="/settings" element={<Menu />} />
</Routes>
</Router>
</Provider>
</>
);
}
是否可以将组件缓存在后台,让状态保持,间隔继续?
【问题讨论】:
-
缓存组件,没有。缓存状态吗?是的。将需要持久化的组件状态移动到 redux 存储中,这样当组件挂载时,它就可以在需要的地方找到它。
标签: reactjs react-redux