React Native结合Redux开发时dispatch登录action后首次无法跳转如何解决
问题原因
- 你使用的
loginUser是基于redux-thunk实现的异步action,dispatch(loginUser(data))触发后不会等待后端登录接口请求完成,会立刻执行后续的auth.isAuth && navigation.navigate('Home')代码。此时接口还未返回结果,redux中的isAuth仍为登录前的false,跳转逻辑不会触发。 useSelector返回的auth是当前组件渲染周期的状态快照,就算后续redux状态更新,本次onSubmit函数作用域内拿到的auth也不会发生变化,哪怕接口请求完成后isAuth被更新为true,这行判断逻辑也已经执行结束,不会二次触发跳转。
解决方案
提供两种可行实现方案,优先推荐第一种声明式写法:
方案1:通过useEffect监听登录状态变化
在Login组件内添加useEffect,监听auth.isAuth的状态变化,当它变为true时自动执行跳转逻辑,该写法更符合React的响应式开发范式:
import { useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useNavigation } from '@react-navigation/native'; // 组件内代码 const dispatch = useDispatch(); const auth = useSelector(state => state.authentication); const navigation = useNavigation(); // 新增状态监听逻辑 useEffect(() => { if (auth.isAuth) { navigation.navigate('Home'); } }, [auth.isAuth, navigation]); const onSubmit = (data: {email: string; password: string}) => { dispatch(loginUser(data)); };
方案2:等待异步action执行完成后主动判断跳转
redux-thunk支持异步action返回Promise,你可以将onSubmit改为异步函数,等待dispatch的登录请求执行完成后再执行跳转:
首先改造异步action,增加返回值标识登录结果:
export const loginUser = data => async dispatch => { try { const res = await axios({ method: 'post', url: `${API_URl}/auth/login`, data, }); dispatch({type: LOGIN_SUCCESS, payload: res.data}); return { success: true }; } catch (error) { dispatch({type: GET_ERRORS, payload: error.response.data}); dispatch({type: LOGIN_FAILED, payload: error.response.data}); return { success: false, error: error.response.data }; } };
再改造Login页面的onSubmit逻辑:
const onSubmit = async (data: {email: string; password: string}) => { const loginResult = await dispatch(loginUser(data)); if (loginResult.success) { navigation.navigate('Home'); } else { // 可在此处添加登录失败的提示逻辑 console.log('登录失败', loginResult.error); } };
内容的提问来源于stack exchange,提问作者smichi
相关产品推荐
相关产品推荐

