我有一个
UserContext
来处理我的应用程序的身份验证。
这是它的样子
const UserProvider = ({ children }: { children: React.ReactNode }) => {
const [user, setUser] = useState<User | null>(null);
const [isLoading, setIsLoading] = useState(true);
const login = async (userName: string, password: string) => {
try {
const { user } = await authlogin(userName, password);
setUser(user);
} catch (e) {
// error handled by api-client
}
};
const logout = () => {
setUser(null);
};
useEffect(() => {
getUser()
.then(({ user }) => setUser(user))
.catch(() => setUser(null))
.finally(() => setIsLoading(false));
}, []);
const isAuthenticated = user !== null;
return (
<UserContext value={{ isLoading, user, isAuthenticated, login, logout }}>
{children}
</UserContext>
);
};
在我的应用程序的其他地方,我有一个
RequireAuth
组件,用于检查当前用户(如果有):
const RequireAuth = ({ children }: { children: ReactNode }) => {
const { isLoading, isAuthenticated } = useUserContext();
if (isLoading) return <div>Loading...</div>;
if (!isAuthenticated) {
return <Navigate to="/login" replace />;
}
return children;
};
我想利用最新的
use
钩子和 React 19 的 Suspense
,但我无法让它在这种情况下工作。它甚至是 use
钩子的用例吗?如果没有,我应该如何让我的 UserContext
与 Suspense 一起使用?
如果我在上下文中执行类似
const { user } = use(getUser());
的操作,那么它会无限循环运行。
如您所见,
login
还需要设置用户。
需要将从
getUser()
返回的 Promise 传递给子组件:
协调react 19 webiste:使用不支持在渲染中创建的承诺。
“要解决这个问题,您需要传递来自悬念驱动库的承诺,或者 支持缓存 Promise 的框架。未来我们计划 提供一些功能,以便更轻松地在渲染中缓存 Promise。”
例如:
const UserProvider = ({ children }: { children: React.ReactNode }) => {
const [user, setUser] = useState<User | null>(null);
const [isLoading, setIsLoading] = useState(true);
const login = async (userName: string, password: string) => {
try {
const { user } = await authlogin(userName, password);
setUser(user);
} catch (e) {
// error handled by api-client
}
};
const logout = () => {
setUser(null);
};
const response = getUser()
const isAuthenticated = user !== null;
return (
<UserContext value={{ response, isLoading, user, isAuthenticated, login, logout }}>
{children}
</UserContext>
);
};
在你的
UserContext
里面:
const UserContext = ({value}:{value:AuthProps})=>{
...//other stuffs
const {response} = value;
data = use(response)
return (
<Suspense fallback={<p>Loading...</p<}>
<ErrorBoundary errorComponent={yourErrorComponent}>
{data}
</ErrorBoundary>
</Suspense>);
}
然后,直到
getUser()
的 Promise 完成,才会显示 Suspense 的后备组件。
我希望这有帮助!