React Native应用程序总是在登录屏幕上打开



我的react本机应用程序有问题。它总是在登录屏幕上打开,但我想在用户已经登录时打开主屏幕。我正在使用AsyncStorage来验证令牌是否为null。如果令牌为空,我会将状态屏幕设置为"登录",如果不是,我会设置状态屏幕为"主"。但我认为导航器是在状态更改之前返回的。但我不知道如何以正确的方式来做。请帮帮我!

我的导航器(我使用的是react navigation v5(

import React, {PureComponent} from 'react'
import { createStackNavigator } from '@react-navigation/stack'
import { NavigationContainer } from '@react-navigation/native'
import AsyncStorage from '@react-native-community/async-storage'
import { connect } from 'react-redux'
import Login from '../screens/Login'
import Register from '../screens/Register'
import Main from '../screens/Main'
import TransactionRegistration from '../screens/TransactionRegistration'
import { renewLogin } from '../store/actions/user'
import '../config/ReactotronConfig'
const StackMain = createStackNavigator()
class Navigator extends PureComponent {
    state = {
        screen: 'Login',
    }
    componentDidMount() {
        this.isLogged()
            .then(res => this.setState({ screen: res}))
            .catch(err => alert('An error occurred'))
    }
    isLogged = async() => {
        let token = await AsyncStorage.getItem('@user_token')
        let id = await AsyncStorage.getItem('@user_id')
        const user = {
            id: id,
            token: token
        }
        if (token !== null) {
            await this.props.onRenewLogin(user)
            return 'Main'
        }
        else {
            return 'Login'
        }
    }
    render() {
        return (
            <NavigationContainer>
                <StackMain.Navigator initialRouteName={this.state.screen}>
                    <StackMain.Screen
                        component={Login}
                        name='Login'
                        options={{headerShown: false}} />
                    <StackMain.Screen
                        component={Register}
                        name='Register'
                        options={{headerShown: false}} />
                    <StackMain.Screen
                        component={Main}
                        name='Main'
                        options={{headerShown: false}} />
                    <StackMain.Screen
                        component={TransactionRegistration}
                        name='TransactionRegistration'
                        options={{headerShown: false}} />
                </StackMain.Navigator>
            </NavigationContainer>
        )
    }
}
const mapDispatchToProps = dispatch => {
    return {
        onRenewLogin: user => dispatch(renewLogin(user)),
    }
}
export default connect(null, mapDispatchToProps)(Navigator)

我的登录屏幕(当登录成功时,请查看我导航到Main(

import React, { PureComponent } from 'react'
import { connect } from 'react-redux'
import { 
    login,
} from '../../store/actions/user'
import {
    View,
    Text,
    Animated,
    StatusBar,
} from 'react-native'
import { validateForm } from '../../common/utils/validators'
import AuthContainer from '../../components/Auth/AuthContainer'
import AuthTitle from '../../components/Auth/AuthTitle'
import AuthButton from '../../components/Auth/AuthButton'
import AuthInput from '../../components/Auth/AuthInput'
import AuthHeader from '../../components/Auth/AuthHeader'
import SpeechBubble from '../../components/Auth/SpeechBubble'
import styles from '../../assets/css/styles'
import { colors } from '../../assets/css/colors'
class Login extends PureComponent {
    state = {
        email: '',
        password: '',
        text: 'Olá! Cadastrou sua conta usando e-mail e senha? Insira-os aqui:',
        messageError: '',
        shakeAnimation: new Animated.Value(0),
        formError: false,
    }
    componentDidUpdate = (prevProps, prevState) => {
        if(prevProps.isLoading && !this.props.isLoading && this.props.token){
            this.props.navigation.navigate('Main')
        }
        if(prevProps.loginError != this.props.loginError && this.props.loginError != ''){
            this.setState({ text: this.props.loginError, formError: true})
        }
        if(prevState.text != this.state.text){
            this.handleAnimation()
        }
    }
    login = async() => {
        this.setState({messageError: validateForm('login', this.state)})
        if (this.state.messageError == '') {
            await this.props.onLogin({ ...this.state })
            if (this.props.loginError != '') {
                this.setState({ text: this.props.loginError, formError: true})
                this.handleAnimation()
            }
        }
        else {
            this.setState({text: this.state.messageError, formError: true})
            this.handleAnimation()
        }
    }
    navigateToRegister = () => {
        this.props.navigation.navigate('Register')
    }
    handleAnimation = () => {
        Animated.sequence([
            Animated.timing(this.state.shakeAnimation, { toValue: 10, duration: 80, useNativeDriver: true }),
            Animated.timing(this.state.shakeAnimation, { toValue: -10, duration: 80, useNativeDriver: true }),
            Animated.timing(this.state.shakeAnimation, { toValue: 10, duration: 80, useNativeDriver: true }),
            Animated.timing(this.state.shakeAnimation, { toValue: 0, duration: 80, useNativeDriver: true })
          ]).start() 
    }
    render(){
        
        return (
            <AuthContainer>
                <StatusBar backgroundColor={colors.screenBg} barStyle='dark-content' />
                <AuthHeader />
                <SpeechBubble>
                    <Animated.View
                        style={{ transform: [{translateX: this.state.shakeAnimation}] }}>
                    <AuthTitle 
                        text={this.state.text} 
                        styleTitle={!this.state.formError ? [styles.loginFont, styles.bodyText] :
                            [styles.loginFont, styles.bodyText, styles.bodyTextError]}/>
                    </Animated.View>
                    <AuthInput
                        placeholder='Seu e-mail'
                        keyboardType='email-address'
                        autoFocus={true}
                        autoCorrect={false}
                        autoCapitalize='none'
                        returnKeyType='next'
                        value={this.state.email}
                        onChangeText={email => this.setState({ email })}
                        blurOnSubmit={false} />
                    <AuthInput 
                        placeholder='Sua senha'
                        returnKeyType='go'
                        value={this.state.password}
                        password={true}
                        onChangeText={password => this.setState({ password })} />
                    <AuthButton title='Entrar' onPress={() => this.login()}/>
                    <View style={styles.bodyBottom}>
                        <Text style={[styles.loginFont, styles.bodyLink]}>Esqueci minha senha</Text>
                        <Text style={[styles.loginFont, styles.bodyLink]} onPress={this.navigateToRegister}>
                            Ainda não cadastrei uma conta
                        </Text>
                    </View>
                </SpeechBubble>
            </AuthContainer>
        )
    }
}
const mapStateToProps = ({ user }) => {
    return {
        isLoading: user.isLoading,
        token: user.token,
        loginError: user.loginError,
    }
}
const mapDispatchToProps = dispatch => {
    return {
        onLogin: user => dispatch(login(user)),
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(Login)

您在第一次渲染时是对的,initialRouteName是Login,如果您将其更改为已渲染登录的状态也没关系,更简单的解决方法是在登录时实际初始化应用程序,然后使用导航道具方法navigation将用户发送到预期屏幕。

因此,在您的组件DidMount 中

componentDidMount = () => {
        this.isLogged()
            .then(res => { 
                this.props.navigation.navigate(res);
            })
            .catch(err => alert('An error occurred'))
    }

相关内容

  • 没有找到相关文章

最新更新