反应对象的本机 setState/useState
Posted
技术标签:
【中文标题】反应对象的本机 setState/useState【英文标题】:React Native setState/useState of an Object 【发布时间】: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
的来源
【参考方案1】:
在@P.hunter、@Erdenezaya 和@Federkun 的帮助下,我得到了正确的答案。
问题在于状态 init 和 setUser()。
-
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>
);
-
设置用户的上下文功能必须这样做:
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
也不是问题。画面不会改变。问题出在上下文中...以上是关于反应对象的本机 setState/useState的主要内容,如果未能解决你的问题,请参考以下文章