【问题标题】:React Native setState/useState of an Object反应对象的本机 setState/useState
【发布时间】:2021-05-17 15:42:50
【问题描述】:

我是 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);
    };

【问题讨论】:

  • 你能澄清initialise first state的意思吗?
  • 我希望我的状态对象具有上面initialLoginState 中所示的属性,以便我可以使用它来有条件地渲染组件。
  • 将计数器设置为 const [counter, setCounter] = useState(0) 然后 setCounter(counter + 1) 递增时类似的东西,但我需要一个具有属性的对象
  • 是的,我现在把问题修改得更清楚。
  • 您可能想分享更多代码,尤其是user 的来源

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


【解决方案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 };
};

感谢大家的帮助!

【讨论】:

    【解决方案2】:

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

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

    我不确定 AuthContext.Provider 是什么,但它正在尝试将对象(用户)呈现为 html 反应元素,请确保您知道 值的数据类型 该组件的prop。

    【讨论】:

    • 上下文提供者的值允许我看到值属性的变化。如果我使用useContext,则可以跨组件访问 setUser。但你是对的,如果我使用不同的值来渲染屏幕,它工作正常......
    【解决方案3】:

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

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

    【讨论】:

    • 略有不同的错误,但仍然...Objects are not valid as a React child (found: object with keys {0, 1, userRole}). If you meant to render a collection of children, use an array instead.
    • 我认为问题出在您正在渲染的 2 个组件内。你能分享 组件吗?
    • 即使换成不同颜色的View也不是问题。画面不会改变。问题出在上下文中...
    猜你喜欢
    • 2021-07-12
    • 2020-07-21
    • 2021-03-12
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 2021-04-19
    • 2021-03-01
    相关资源
    最近更新 更多