提问者:小点点

react native中的redux身份验证状态有问题


我使用react native和redux,但性能很慢.例如,在初始页面上,我有一个检查系统,如果处于还原状态的用户通过了身份验证,则显示home page,如果没有显示auth屏幕。

当我的用户通过身份验证时,我的应用程序最初会呈现身份验证屏幕几秒钟,然后呈现主屏幕,这是一个糟糕的用户体验,所以我的redux状态可能需要时间更新,而且速度很慢。

请看我的代码并帮助我做错了什么。

我正在检查异步存储中的已验证令牌以确定已验证的用户。

const Root = (props) => {


    useEffect(() => {
        const bootstrapAsync = async () => {
          let token;
        //   token = null;
          try {
            token = await AsyncStorage.getItem('FBIdToken');
          } catch (e) {
            console.log(e);
          }
          if(token !== null){
            const decodedToken = jwtDecode(token);
            if(decodedToken.exp * 1000 < Date.now()) {
              store.dispatch(logoutUser());
            } else {
              store.dispatch({ type: SET_AUTHENTICATED });
              store.dispatch(getUserData());
            }
          }
        };
        bootstrapAsync();
        setIsLoading(false);
      }, []);



    return (
        <NavigationContainer ref={navigationRef}>
        { 
        !props.user.authenticated ? (
            <AuthStackScreen />
        ) : (
            <DrawerScreen />
        )
        }
      </NavigationContainer>
    )
};

const mapStateToProps = (state) => ({
    user: state.user,
    UI: state.UI
});


export default connect(mapStateToProps)(Root);

reducers.js

import { SET_USER, SET_AUTHENTICATED, SET_UNAUTHENTICATED } from '../types';

const initialState = {
    authenticated: false,
    loading: false,
    credentials: {},
    likes: [],
    notifications: []
};

export default function(state = initialState, action){
    switch(action.type){
        case SET_AUTHENTICATED:
            return {
                ...state,
                authenticated: true
            };
        case SET_UNAUTHENTICATED:
            return initialState;
        case SET_USER:
            return {
                authenticated: true,
                loading: false,
                ...action.payload
            };
        default:
            return state;

    }
}

共1个答案

匿名用户

您有多个选项

  • 显示加载屏幕
  • 绕过表达式
  • 默认已验证为true

我更喜欢的解决方案(我已经这样做了很多次):

  • 创建一个名为StartupScreen
  • 的自己的屏幕
  • 在其中执行所有与登录相关的操作
  • 在其中显示ActivityIndicator

我的例子:

const StartupScreen = () => {

    const dispatch = useDispatch()

    useEffect(() => {
        const tryLogin = async () => {
            const userData = await AsyncStorage.getItem(USER_DATA)

            if (!userData) {
                dispatch(setDidTryAL())
                return
            }

            const parsedUserData = JSON.parse(userData)
            const {user_id, access_token, expires_at} = parsedUserData
            const expirationDate = new Date(expires_at * 1000)

            if (expirationDate <= new Date() || !access_token | !user_id) {
                dispatch(setDidTryAL())
                return
            }

            const userDetails = JSON.parse(await AsyncStorage.getItem(USER_DETAILS))

            dispatch({type: AUTHENTICATE, user_id, access_token, expires_at, userDetails})
        }

        tryLogin()
    }, [dispatch])

    return (
        <View style={styles.screen}>
            <ActivityIndicator size='large' color={Colors.primary}/>
        </View>
    )
}

export default StartupScreen

和我的根导航器(现代方法):

const AppNavigator = () => {
    const isAuthenticated = useSelector(state => !!state.auth.access_token)
    const didTryAutoLogin = useSelector(state => state.auth.didTryAutoLogin)
    
    return (
        <SafeAreaProvider>
            <NavigationContainer>
                { !isAuthenticated && didTryAutoLogin && <LoginAndRegisterNavigator/> }
                { !isAuthenticated && !didTryAutoLogin && <StartupScreen/>}
            </NavigationContainer>
        </SafeAreaProvider>
    )
}
export default AppNavigator

对我来说,我甚至无法看到加载屏幕,因为登录进程工作得太快了。此外,屏幕的背景颜色应该与用户稍后能够看到的背景颜色相同。他甚至不会注意到装货的东西。