Reputation: 530
I am new to React Native and don't quite understand the concept of initial states of an object and updating the state when I have more than one property to set.
the error (edit #2):
Objects are not valid as a React child (found: object with keys {userRole}). If you meant to render a collection of children, use an array instead.
App.js
const initialLoginState = {
userRole: null,
userId: null,
};
const [user, setUser] = useState(initialLoginState);
const [isReady, setIsReady] = useState(false);
const restoreUser = async () => {
const user = await authStorage.getUser();
if (user) setUser(user);
};
if (!isReady) {
return (
<AppLoading
startAsync={restoreUser}
onFinish={() => setIsReady(true)}
onError={console.warn}
/>
);
}
//render
return (
<AuthContext.Provider value={{ user, setUser }}>
<NavigationContainer>
{user.userRole ? <ViewTest /> : <AuthNavigator />}
</NavigationContainer>
</AuthContext.Provider>
);
useAuth which updates the user when I received the data:
const logIn = (data, authToken) => {
setUser((prevState) => ({
userRole: {
...prevState.userId,
userRole: data.USERROLE,
},
}));
authStorage.storeToken(data.USERID);
};
Upvotes: 0
Views: 711
Reputation: 530
I was able to get the right answer with the help of @P.hunter, @Erdenezaya and @Federkun.
The problem was in the state init and setUser().
const initialLoginState = {
userRole: null,
userId: null,
};
const [user, setUser] = useState({
initialLoginState,
});
const [isReady, setIsReady] = useState(false);
const restoreUser = async () => {
const user = await authStorage.getUser();
if (user) setUser(user);
};
if (!isReady) {
return (
<AppLoading
startAsync={restoreUser}
onFinish={() => setIsReady(true)}
onError={console.warn}
/>
);
}
//syntax error was found in {user.userRole}
return (
<AuthContext.Provider value={{ user, setUser }}>
<NavigationContainer>
{user.userRole ? <ViewTest /> : <AuthNavigator />}
</NavigationContainer>
</AuthContext.Provider>
);
export default useAuth = () => {
const { user, setUser } = useContext(AuthContext);
const logIn = (data, authToken) => {
setUser({ ...user, userRole: data.USERROLE });
authStorage.storeToken(data.USERID);
};
const logOut = () => {
setUser({ ...user, userRole: null });
authStorage.removeToken();
};
return { user, logIn, logOut };
};
Thank you all for your help!
Upvotes: 1
Reputation: 1365
Objects are not valid as a React child (found: object with keys {userRole}). If you meant to render a collection of children, use an array instead.
<AuthContext.Provider value={{ user, setUser }}> // <---- the problem is here
<NavigationContainer>
{user.userRole ? <ViewTest /> : <AuthNavigator />}
</NavigationContainer>
</AuthContext.Provider>
I'm not sure what AuthContext.Provider is, but it's trying to render the object(User) as html react elements, make sure you know what sort of data the value prop of that component takes.
Upvotes: 1
Reputation: 141
You don't need prevState in functional component. user is the prevState before you set new state
const logIn = (data, authToken) => {
setUser({...user, userRole: data.USERROLE});
authStorage.storeToken(data.USERID);
};
Upvotes: 1