首页 > 解决方案 > 反应倒计时

问题描述

我有一个倒数计时器片段,反应如下:

const [remainingTime, setRemainingTime]: [number, Dispatch<SetStateAction<number>>] = useState<number>(0);
const [updatedTime, setUpdatedTime]: [number, Dispatch<SetStateAction<number>>] = useState<number>(0);
const referenceTime = useRef<number>(0); // new Date().getTime()
const intervalRef = useRef<number>(updatedTime);

const decreaseTime = () =>
        setUpdatedTime((prevState) => {
            if (prevState > 1) {
                    return parseFloat(((updatedTime * 1000 + referenceTime.current - Date.now()) / 1000).toFixed(0));
            } else {
                setRemainingTime(0);
                return 0;
            }
        });
    
    useEffect(() => {
        if (remainingTime > 0) {
            intervalRef.current = setInterval(decreaseTime, 1000) as unknown as number;
        }

        return () => clearInterval(intervalRef.current);
}, [remainingTime]);

一切正常,直到我想为其添加增量和减量选项。有必要使用 Date.now() 和 referenceTime 因为这个模块用于 react-native 并且它必须在后台模式下工作,所以我应该在哪里改变一些东西来正确升级状态。我尝试了以下解决方案:

setUpdatedTime((prevState) => prevState + 10)

setUpdatedTime((prevState) => updatedTime + 10)

更新: https ://codesandbox.io/s/react-countdown-timer-lr9sb

谢谢您的帮助。:)

标签: javascriptreactjstypescriptreact-native

解决方案


如果有人处于相同情况的解决方案: https ://codesandbox.io/s/react-countdown-timer-lr9sb?file=/src/App.tsx

const [remainingTime, setRemainingTime]: [number, Dispatch<SetStateAction<number>>] = useState<number>(0);
const [updatedTime, setUpdatedTime]: [number, Dispatch<SetStateAction<number>>] = useState<number>(0);
const referenceTime = useRef<number>(0); // new Date().getTime()
const intervalRef = useRef<number>(updatedTime);

const decreaseTime = () =>
        setUpdatedTime((prevState) => {
            const difference = parseFloat((Date.now() - referenceTime.current - 1000).toFixed(0))
            if (prevState > 1) {
                    return parseFloat(((prevState * 1000 + referenceTime.current - Date.now() + (difference)) / 1000).toFixed(0));
            } else {
                setRemainingTime(0);
                return 0;
            }
        });
    
    useEffect(() => {
        if (remainingTime > 0) {
            intervalRef.current = setInterval(decreaseTime, 1000) as unknown as number;
        }

        return () => clearInterval(intervalRef.current);
}, [remainingTime]);

推荐阅读