如何避免页面与API未完全加载时useEffect触发错误重定向?
解决登录后首页错误重定向的问题
问题根源是useGetUser初始加载时,isLoading和data同时为false,导致useEffect误判为用户未认证,触发重定向。可以通过以下几种方式解决:
方式一:新增状态追踪请求是否完成
在组件里加一个状态标记请求是否已经完成,只有请求完成后再判断是否重定向:
const page = () => { const router = useRouter(); const {data, isLoading} = useGetUser(); const [hasFetched, setHasFetched] = useState(false); // 当isLoading变为false时,标记请求完成 useEffect(() => { if (!isLoading) { setHasFetched(true); } }, [isLoading]); // 仅在请求完成且无用户数据时重定向 useEffect(() => { if (hasFetched && !data) { router.push('/create-account'); } }, [hasFetched, data, router]); if (isLoading) { return <spinner />; } return <Home />; };
方式二:区分初始状态与无数据状态
如果useGetUser的初始data可以设为undefined(而非false),可以直接通过判断data的具体值来避免误判:
const page = () => { const router = useRouter(); const {data, isLoading} = useGetUser(); // 初始data为undefined useEffect(() => { if (isLoading) return; // 只有当data明确为false(请求后确认无用户)才跳转 if (data === false) { router.push('/create-account'); } }, [isLoading, data, router]); if (isLoading) { return <spinner />; } return <Home />; };
方式三:完善useGetUser的初始状态
如果能修改useGetUser钩子,让它初始时isLoading为true,直到请求完成再改为false,从根源避免初始状态异常:
// 改进后的useGetUser钩子 const useGetUser = () => { const [data, setData] = useState(undefined); const [isLoading, setIsLoading] = useState(true); // 初始设为true useEffect(() => { const fetchUser = async () => { try { const res = await fetch('/api/user'); const userData = await res.json(); setData(userData || false); } catch (error) { setData(false); } finally { setIsLoading(false); // 请求结束后再设为false } }; fetchUser(); }, []); return {data, isLoading}; };
这样修改后,原组件的逻辑就能正常工作,不会出现初始时isLoading和data同时为false的情况。
内容的提问来源于stack exchange,提问作者wdev733
相关产品推荐
相关产品推荐

