React Native setState/useState of an Object

时间:2021-02-14 14:32:36

标签: javascript reactjs react-native expo use-state

我是 React Native 的新手,不太了解对象的初始状态以及当我有多个属性要设置时更新状态的概念。

错误(编辑#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 在我收到数据时更新用户:

const logIn = (data, authToken) => {
        setUser((prevState) => ({
            userRole: {
                ...prevState.userId, 
                userRole: data.USERROLE,
            },
        }));
        authStorage.storeToken(data.USERID);
    };

3 个答案:

答案 0 :(得分:1)

您不需要在功能组件中使用 prevState。 user 是设置新状态之前的 prevState

const logIn = (data, authToken) => {
  setUser({...user, userRole: data.USERROLE});
  authStorage.storeToken(data.USERID);
};

答案 1 :(得分:1)

<块引用>

对象作为 React 子对象无效(找到:带有键 {userRole} 的对象)。如果您打算渲染一组子项,请改用数组。

    <AuthContext.Provider value={{ user, setUser }}>  // <---- the problem is here
        <NavigationContainer>
            {user.userRole ? <ViewTest /> : <AuthNavigator />}
        </NavigationContainer>
    </AuthContext.Provider>

我不确定 AuthContext.Provider 是什么,但它试图将对象(用户)呈现为 html 反应元素,请确保您知道 值< /strong> 该组件的 prop 需要。

答案 2 :(得分:1)

在@P.hunter、@Erdenezaya 和@Federkun 的帮助下,我得到了正确的答案。

问题出在 init 和 setUser() 状态。

  1. 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}
            />
        );
    }

    //syntax error was found in {user.userRole}
    return (
        <AuthContext.Provider value={{ user, setUser }}>
            <NavigationContainer>
                {user.userRole ? <ViewTest /> : <AuthNavigator />}
            </NavigationContainer>
        </AuthContext.Provider>
    );
  1. 用于设置用户的上下文功能必须像这样完成:
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 };
};

谢谢大家的帮助!