reactjs Async React Context getting“不能用作JSX组件”

w6lpcovy  于 2023-11-18  发布在  React
关注(0)|答案(1)|浏览(193)

我试图创建一个context用于保存登录的数据,但我在尝试使用provider时遇到了一个问题,我的IDE显示:
MyContextProvider不能用作JSX组件。
它的返回类型Promise不是有效的JSX元素。
类型Promise缺少类型ReactElement<any,>any>中的以下属性:type,props,key

MyContext

import React, {createContext, useCallback, useState} from 'react';
// Other imports

const initialContext = {
  loggedIn: false,
  user: undefined,
  handleLoggedIn: () => {},
  handleUser: () => {},
  ...
};

export const MyContext = createContext(initialContext);

const getLoggedIn = async () => await new UserService().isLoggedIn();
const getUser = async () => await new UserService.getProfile().then(u => u.Data);

export const MyContextProvider = async (props: any) => {
  const [loggedIn, setLoggedIn] = useState(await getLoggedIn());
  const [user, setUser] = useState<ProfileModel>(await getUser());
  // More similar pieces...

  const handleLoggedIn = useCallback(async isLoggedIn => setLoggedIn(isLoggedIn), []);
  const handleUser = useCallback(async userData => setUser(userData), []);
  // More similar pieces...

  return (
    <MyContext.Provider
      value={{
        loggedIn,
        user,
        handleLoggedIn,
        handleUser
        ...
      }}>
      {props.children}
    </LoggedInContext.Provider>
  );
};

字符串
用法:我实际上 Package 了一些React-Native导航器屏幕

const someStack = createStackNavigator();

const MyStack = () => (
  <MyContextProvider>
    <someStack.Navigator screenOptions={{ title: 'Some screen' }}>
        <someStack.Screen name="Home" component={SomeAccountComp} />
        <someStack.Screen name="Orders" component={SomeOrdersComp} options={{title: "My Orders" }} />
    </myAccount.Navigator>
  </LoggedInContextProvider>
);


在这一点上,我得到的错误消息。

rmbxnbpk

rmbxnbpk1#

JS中的每个async函数都返回一个Promise。React组件不允许这样做。
因此,一种可能的解决方法是为上下文提供程序的状态提供一个默认值,并在解析后设置该值:

// no async allowed
const MyContextProvider = ()=>{
  const [loggedIn, setLoggedIn] = useState(false); // may consider to have a third, "uninitialized" value for initial state
  useEffect(()=>{
     let stillLoaded = true;
     const loadLoggedIn = async ()=>{
        const loggedIn = await getLoggedIn();
        if(stillLoaded) {
           setLoggedIn(loggedIn);
        }
     }
     return ()=>{stillLoaded = false};
  }, []);
  // [...]
}

字符串

相关问题