如何防止加载用户数据时显示不同的页面?



我在Next.js 13中有这个应用程序,我根据一些变量显示不同的页面,但每次它都显示逐页,直到我得到正确的一个。在应用程序知道该显示哪个页面之前,你能否通过加载屏幕来避免这种情况?

我代码:

import { useRouter } from "next/navigation"
import Login from "../../components/auth/Login"
import Particle from "../../components/Particle"
import Plans from "../../components/stripe/Plans"
import { useUserContext } from "./../context/userContext"
import { ArrowLeft } from "phosphor-react"
function HomePage() {
const router = useRouter()
const { user, premiumStatus, unlock, logoutUser } = useUserContext()
return (
<>
{!user ? (
<Login />
) : (
<div>
{!premiumStatus ? (
<div className="flex h-screen justify-center" >
<Particle/>
<button onClick={logoutUser} title="Logout" className="fixed top-0 left-0 text-white p-4" ><ArrowLeft className="w-10 h-10" /></button>
{unlock && <Plans/>}
</div>
) : (
router.replace("../dashboard")
)}
</div>
)}
</>
)
}

假设您正在从服务器请求用户数据,这需要一些时间。您需要一种机制来让组件知道何时发生这种情况。在上下文中使用一个简单的状态变量就可以做到这一点。

在上下文中

const [loading, setLoading] = useState(false);
fetchUserData(){
try {
setLoading(true);
...
} catch(...) {
...
} finally {
setLoading(false);
}
}

为了更好地组织,我建议使用保护子句,而不是巨大的链式条件:

function HomePage() {
const router = useRouter();
// Add the loading state
const { user, loading, premiumStatus, unlock, logoutUser } = useUserContext(); 

// Make a loading component, something fun to look at
if (loading) return <Loading/>; 
if (!user) return <Login/>;
// I would probably make this its own component.
if (!premiumStatus)
return (
<div className="flex h-screen justify-center">
<Particle />
<button
onClick={logoutUser}
title="Logout"
className="fixed top-0 left-0 text-white p-4"
>
<ArrowLeft className="w-10 h-10" />
</button>
{unlock && <Plans />}
</div>
);

// All checks pass, reroute to dashboard.
router.replace("../dashboard");
return null;
}