javascript - 如果用户为空,则反应 useEffect。重定向
问题描述
我正在尝试在下一个 JS 中创建一条受保护的路线。如果没有用户到登录页面,我添加了一个使用效果来重定向
const analytics = () => {
const { userLoaded, user, signOut, session, userDetails, subscription } =
useUser();
const router = useRouter();
console.log(session);
useEffect(() => {
setInterval(() => {
if (!session) router.replace("/admindashboard");
}, 3000);
}, [session]);
return (
<>
<Dashboard />
<p>Coming soon</p>
</>
);
};
导出默认分析;
问题是我正在为我调用用户的 supabase 使用自定义钩子。当页面由于某种原因加载时它是 null 然后对用户来说是 true 但是因为它是 null 它在不需要时重定向我对如何防止这种情况感到困惑
语境
import { useEffect, useState, createContext, useContext } from "react";
import { supabase } from "../utils/supabaseClient";
export const UserContext = createContext();
export const UserContextProvider = (props) => {
const [userLoaded, setUserLoaded] = useState(false);
const [session, setSession] = useState(null);
const [user, setUser] = useState(null);
const [userDetails, setUserDetails] = useState(null);
const [subscription, setSubscription] = useState(null);
useEffect(() => {
const session = supabase.auth.session();
setSession(session);
setUser(session?.user ?? null);
const { data: authListener } = supabase.auth.onAuthStateChange(
async (event, session) => {
setSession(session);
setUser(session?.user ?? null);
}
);
return () => {
authListener.unsubscribe();
};
}, []);
const updateAvatar = (url) =>
supabase.auth.update({
data: { avatar_url: url },
});
const updateCardFav = async (favId) =>
await supabase.from("user_faved").insert([{ name: favId }]);
const updateUserName = (userEnteredName) => {
supabase.auth.update({
data: { full_name: userEnteredName },
});
};
const getUserDetails = () => supabase.from("users").select("*").single();
const getSubscription = () =>
supabase
.from("subscriptions")
.select("*, prices(*, products(*))")
.in("status", ["trialing", "active"])
.single();
useEffect(() => {
if (user) {
Promise.allSettled([getUserDetails(), getSubscription()]).then(
(results) => {
setUserDetails(results[0].value.data);
setSubscription(results[1].value.data);
setUserLoaded(true);
}
);
}
}, [user]);
const value = {
session,
user,
updateCardFav,
userDetails,
updateUserName,
userLoaded,
subscription,
updateAvatar,
signIn: (options) => supabase.auth.signIn(options),
signUp: (options) => supabase.auth.signUp(options),
signOut: () => {
setUserDetails(null);
setSubscription(null);
return supabase.auth.signOut();
},
};
return <UserContext.Provider value={value} {...props} />;
};
export const useUser = () => {
const context = useContext(UserContext);
if (context === undefined) {
throw new Error(`useUser must be used within a UserContextProvider.`);
}
return context;
};
解决方案
您只需将 isLoading 添加到用户即可,这很简单。
isLoading 的第一个值必须为真。
useEffect(() => {
if (!isLoading && !user) {
router.push("/admindashboard");
return;
}
return;
}, [user, isLoading]);
在你的钩子里
const [isLoading, setLoading] = useState(true)
useEffect(() => {
if (user) {
Promise.allSettled([getUserDetails(), getSubscription()]).then(
(results) => {
setUserDetails(results[0].value.data);
setSubscription(results[1].value.data);
setUserLoaded(true);
setLoading(false);
}
).catch(err => {
console.log(err);
setLoading(false);
setUserLoaded(false);
});
}
}, [user]);
推荐阅读
- postgresql - 在谷歌 CloudSQL 中备份 PostgresSQL 单个数据库(非实例)的最佳方法是什么
- php - Laravel 为 foreach() 问题提供的参数无效
- android - Android Studio 正确编译项目,Gradlew 没有启用数据绑定
- selenium - selenium chrome驱动程序在c#中选择证书弹出确认
- sharepoint - 将大文件上传到 SharePoint 2016 会挂起整个服务器
- python - 应在至少 2 个输入的列表上调用“连接”层
- time-complexity - 当条件依赖于其他变量时,如何解决单循环复杂性?
- linux - linux bash 和 grep 错误?
- python - 使用 Python 删除 CSV 文件中的行
- kubernetes - 无法理解 ESX VM 上具有 Kubernetes 集群的节点上的 dmesg 输出