Next.js中的Date.getTime()返回奇怪的数字



我正在尝试在Next.js中进行页面转换。由于转换速度慢于页面加载速度,我需要计算动画完成所需的时间。转换应至少持续2秒,加载屏幕的淡入时间为1s,加载屏幕停留一点时间为500ms,退出时间为500ms。

实际上,我正试图使用new Date.getTime()来实现这一点,并获取动画开始后经过的时间。

我尝试使用以下代码来检查代码是否正确:

function testDateValues() {
var startTime = new Date().getTime();
var animDuration = 1500; // In milliseconds
setTimeout(() => {
console.log(animDuration - (new Date().getTime() - startTime));
}, 1000);
}

此功能打印1秒后丢失的时间,即500ms(打印498-502之间的数字,但它是正确的(。

然而,当我将此代码转换为Next.js时,我会得到像-19604-60418这样的数字,以及与剩余动画时间无关的数字。

代码如下(减少(:

import { useRouter } from 'next/router';
import { useState } from 'react';
export default function LoadingScreen() {
const router = useRouter();    
const [loading, setLoading] = useState(false);
const [loadingStartTime, setLoadingStartTime] = useState(new Date().getTime());
useEffect(() => {
const handleStart = () => {
console.log("Loading started");
setLoading(true);
setLoadingStartTime(new Date().getTime());
};
const handleComplete = () => {
console.log("Loading completed");
console.log(1500 - (new Date().getTime() - loadingStartTime));
setTimeout(() => {
setLoading(false);
}, 1500 - (new Date().getTime() - loadingStartTime));
};
router.events.on("routeChangeStart", handleStart);
router.events.on("routeChangeComplete", handleComplete);
router.events.on("routeChangeError", handleComplete);
return () => {
router.events.off("routeChangeStart", handleStart);
router.events.off("routeChangeComplete", handleComplete);
router.events.off("routeChangeError", handleComplete);
};
}, []);
return {loading && (<div>Loading</div>)}
}

加载屏幕在components/layout.jsx文件中。

import LoadingScreen from "./LoadingScreen";
export default function Layout({ children }) {
return (
<>
<motion.main>{children}</motion.main>
<LoadingScreen />
</>
)
}

加载屏幕甚至有一段时间没有显示。没有页面转换。

为什么几乎相同的代码返回的值如此不同?(为什么是-19604而不是500?(

您的问题是loadingStartTime是在组件加载时初始化的,而该常数值就是效果中的代码将使用的值。setLoadingStartTime调用对const上的闭合值没有影响,它所做的只是导致组件重新渲染。但是,这不会导致效果再次运行。

有多种方法可以解决这个问题:

  • 不使用loadingStartTime的状态,而只是在效果处理程序范围中使用一个可变变量:

    export default function LoadingScreen() {
    const router = useRouter();    
    const [loading, setLoading] = useState(false);
    useEffect(() => {
    let loadingStartTime = Date.now();
    //      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    const handleStart = () => {
    console.log("Loading started");
    setLoading(true);
    loadingStartTime = Date.now();
    //          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    };
    const handleComplete = () => {
    console.log("Loading completed");
    console.log(1500 - (Date.now() - loadingStartTime));
    setTimeout(() => {
    setLoading(false);
    }, 1500 - (Date.now() - loadingStartTime));
    };
    router.events.on("routeChangeStart", handleStart);
    router.events.on("routeChangeComplete", handleComplete);
    router.events.on("routeChangeError", handleComplete);
    return () => {
    router.events.off("routeChangeStart", handleStart);
    router.events.off("routeChangeComplete", handleComplete);
    router.events.off("routeChangeError", handleComplete);
    };
    }, []);
    return {loading && (<div>Loading</div>)}
    }
    
  • 不要为loadingStartTime使用状态,而是在转换开始时初始化的常数:

    export default function LoadingScreen() {
    const router = useRouter();    
    const [loading, setLoading] = useState(false);
    useEffect(() => {
    const handleStart = () => {
    console.log("Loading started");
    setLoading(true);
    const loadingStartTime = Date.now();
    //          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    const handleComplete = () => {
    console.log("Loading completed");
    console.log(1500 - (Date.now() - loadingStartTime));
    setTimeout(() => {
    setLoading(false);
    }, 1500 - (Date.now() - loadingStartTime));
    };
    router.events.once("routeChangeComplete", handleComplete);
    router.events.once("routeChangeError", handleComplete);
    };
    router.events.on("routeChangeStart", handleStart);
    return () => {
    router.events.off("routeChangeStart", handleStart);
    };
    }, []);
    return {loading && (<div>Loading</div>)}
    }
    

    请注意,即使在组件卸载后,这也会保留完整和错误处理程序,这可能是可取的,也可能不是可取的,或者根本不重要。

  • 使用两种具有适当依赖性的独立效果:

    export default function LoadingScreen() {
    const router = useRouter();    
    const [loading, setLoading] = useState(false);
    const [loadingStartTime, setLoadingStartTime] = useState(Date.now());
    useEffect(() => {
    const handleStart = () => {
    console.log("Loading started");
    setLoading(true);
    setLoadingStartTime(Date.now());
    };
    router.events.on("routeChangeStart", handleStart);
    return () => {
    router.events.off("routeChangeStart", handleStart);
    };
    }, []);
    useEffect(() => {
    //  ^^^^^^^^^
    console.log("New loadingStartTime", Date(loadingStartTime));
    const handleComplete = () => {
    console.log("Loading completed");
    console.log(1500 - (Date.now() - loadingStartTime));
    setTimeout(() => {
    setLoading(false);
    }, 1500 - (Date.now() - loadingStartTime));
    };
    router.events.on("routeChangeComplete", handleComplete);
    router.events.on("routeChangeError", handleComplete);
    return () => {
    router.events.off("routeChangeComplete", handleComplete);
    router.events.off("routeChangeError", handleComplete);
    };
    }, [loadingStartTime]);
    //      ^^^^^^^^^^^^^^^^
    return {loading && (<div>Loading</div>)}
    }
    

相关内容

  • 没有找到相关文章

最新更新