Issue
I am trying to create a context
to be used for holding logged in data, but I am facing an issue when trying to use the provider
whereby my IDE is stating:
MyContextProvider cannot be used as a JSX component.
Its return type Promise is not a valid JSX element.
Type Promise is missing the following properties from type 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>
);
};
Usage: I am actually wrapping some React-Native navigator screens
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>
);
It's at this point that I'm getting the error messages.
Solution
Every async
function in JS returns a Promise.
This is not allowed for React components.
So one possible fix is to provide a default value for the context provider's state and set it once the async function resolves:
// 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);
}
}
loadLoggedIn();
return ()=>{stillLoaded = false};
}, []);
// [...]
}
Answered By - Taxel
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.