如何在React Native中使用async/await实现SQLite校验后的动态路由跳转
问题根本原因
- 你定义的
validateUserFunc是异步执行的,调用后不会阻塞后续代码执行,组件渲染时数据库查询还没返回结果,initialRouteName用的还是初始赋值的ValidateUser。 - 你修改的
initialRouteName是普通变量,变更不会触发React组件重渲染,就算后续异步请求返回了正确值,导航器也不会感知到变更。 - React函数组件必须同步返回JSX,所以不能给组件加
async标识,加了必然报错。
解决方案
通过状态控制加载流程,等拿到数据库的用户校验结果后再渲染导航器:
- 新增两个状态:
isLoading控制加载状态,initialRoute存储最终要跳转的初始路由 - 把异步查询逻辑放到
useEffect中,组件挂载时执行一次,查询完成后更新状态触发重渲染 - 加载阶段返回加载UI,加载完成后再渲染导航容器,此时传入的
initialRouteName就是正确的目标路由
修改后的核心代码
// 原有import保留,新增react的hooks导入 import { useState, useEffect } from 'react' import { ActivityIndicator } from 'react-native' const Stack = createStackNavigator() const MainNavigationContainer = (props) => { console.log("MainNavigationContainer props", props) // 新增状态 const [isLoading, setIsLoading] = useState(true) const [initialRoute, setInitialRoute] = useState("ValidateUser") async function validateUserFunc () { try { const validatedUser = await Users.findBy({isAdmin_eq: 1}) console.log('validatedUser in validateUserFunc: ', validatedUser) props.setValidatedUser(validatedUser) const targetRoute = validatedUser?.isValidated === 1 ? "MainTabs" : "ValidateUser" setInitialRoute(targetRoute) console.log('initialRouteName in validateUserFunc: ', targetRoute) } catch (err) { // 可自行添加错误处理逻辑,此处默认走校验页 console.error('获取用户校验状态失败', err) setInitialRoute("ValidateUser") } finally { setIsLoading(false) } } // 组件挂载时仅执行一次查询 useEffect(() => { validateUserFunc() }, []) // 加载阶段返回加载动画,可替换为项目自定义加载组件 if (isLoading) { return <ActivityIndicator size="large" style={{flex: 1, justifyContent: 'center'}} /> } return ( <NavigationContainer> <Stack.Navigator screenOptions={screenOptions} initialRouteName={initialRoute} > {/* 保留原有Stack.Screen配置 */} </Stack.Navigator> </NavigationContainer> ) } // 原有mapStateToProps、connect逻辑保持不变
注意事项
- 导航器的
initialRouteName仅在初始化时生效,如果后续需要动态切换路由,要调用navigation.reset方法重置路由栈,不要直接修改initialRouteName - 建议根据实际业务需求调整加载页的样式和交互,避免用户等待时产生困惑
内容的提问来源于stack exchange,提问作者oktem
相关产品推荐
相关产品推荐

