我可以在上下文中使用 `use` 钩子来从 Promise 中获取数据吗

问题描述 投票:0回答:1

情况

我有一个

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
还需要设置用户。

javascript reactjs typescript react-hooks
1个回答
0
投票

需要将从

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 的后备组件。

我希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.