【问题标题】:react navigation in react native, with conditional stack, and authenticationreact native 中的导航,带有条件堆栈和身份验证
【发布时间】:2020-05-25 16:16:06
【问题描述】:

import React, { Component } from 'react'
import { Container, Content, Form, Item, Input, Label, Button,Text, Icon} from 'native-base'
import AsyncStorage from '@react-native-community/async-storage';
import authStore from '../store/authStore';
export default class Login extends Component {
    constructor(props){
        super(props);
        this.state={
            email:'',
            password:''
        }
    }
    handleLogin = async () =>{
        let requestObject = {
            email: this.state.email,
            password: this.state.password
        }
        authStore.userLogin(requestObject, response => {
            this.storeUserData(response.data.data);
            this.props.navigation.navigate('Home');
        })
    }
    storeUserData = async (value) => {
        try {
          const jsonValue = JSON.stringify(value)
          await AsyncStorage.setItem('@userData', jsonValue)
        } catch (e) {
          console.log(e);
        }
    }
    render() {
        return (
            <Container>
                <Content contentContainerStyle={{flex: 1, justifyContent:'center'}}>
                <Form style={{margin:10}}>
                    <Item rounded last style={{margin:10}}>
                    <Icon active type="FontAwesome" name='user' />
                    <Input placeholder='User Name' 
                    onChangeText={(email)=>this.setState({email})} 
                    value={this.state.email}/>
                    </Item>
                    <Item rounded last style={{margin:10}}>
                    <Icon active type="FontAwesome" name='key' />
                    <Input placeholder='Password'
                    secureTextEntry
                    onChangeText={(password)=>this.setState({password})} 
                    value={this.state.password}/>
                    </Item>
                    <Button rounded block style={{margin:10}} onPress={() => this.handleLogin()}>
                    <Text>Sign-In</Text>
                    </Button>
                </Form>
                </Content>
            </Container>
        )
    }
}
const AuthStack = createStackNavigator();
AuthStackScreen = () =>
      <AuthStack.Navigator>
        <AuthStack.Screen name="Login" component={Login} />
      </AuthStack.Navigator>
HomeStackScreen = () =>
  <HomeStackDrawer.Navigator>
    <HomeStackDrawer.Screen name="Home" component={HomeScreen}/>
    <HomeStackDrawer.Screen name="Form" component={FormScreen}/>
    <HomeStackDrawer.Screen name="Logout" component={Logout}/>
  </HomeStackDrawer.Navigator>
export default class App extends Component{
  constructor(props){
    super(props);
    this.state={
      isloggedIn:false
    }
    this.loginStatusCheck();
  }
  loginStatusCheck = async () =>{
    const userToken = await AsyncStorage.getItem('@accessToken');
    if (userToken) {
      this.setState({isloggedIn:true})
    } else {
      this.setState({isloggedIn:false})
    }
  }
  render(){
    return(
      <NavigationContainer>
        {this.state.isloggedIn ? <HomeStackScreen/> : <AuthStackScreen/>}
      </NavigationContainer>
    )
  }
}

这是我的 App.js,我正在检查用户是否登录,然后相应地加载导航堆栈。我知道问题所在,如果我注销,我想导航到登录组件,但 this.props.navigation.navigate('Login') 给出错误。因为我没有返回Login 路线。如何解决这个问题?另外,当我Log in 出现同样的问题时,因为堆栈中不存在Login。 提前谢谢你

包含登录组件

【问题讨论】:

  • 为什么要使用导航返回登录?将根据您所在状态的 isLogged 呈现正确的堆栈
  • 这里的逻辑是打开应用时检查。但是如果用户没有登录,登录组件就会被渲染。现在,从 Login 组件,应用程序应该导航到 Home。该怎么做?

标签: react-native react-navigation


【解决方案1】:

您必须进行一些更改才能解决此问题。您的问题是您试图访问导航堆栈中不存在的屏幕。 而最大的问题是在 App.js 中使用状态变量来处理导航堆栈的切换。您可以通过在应用程序的上下文中维护登录状态来解决此问题。您也可以从其他屏幕更新它。更新登录状态后,您不必担心导航,App.js 中的状况将为您管理。

代码应该如下所示。我已经给出了一个示例登录组件,它将更新上下文。您将不得不切换到功能组件。从你的代码我看不出这样做有什么问题。

const AppContext = createContext({
  isloggedIn: {},
  setLoggedIn: () => {},
});

const Login = () => {
  const { setLoggedIn } = useContext(AppContext);

  return (
    <View>
      <Button onPress={() => setLoggedIn(true)} />
    </View>
  );
};

export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isloggedIn: false,
      loading: true,
    };
    this.loginStatusCheck();
  }

  setLoggedIn = value => {
    this.setState({ isloggedIn: value });
  };

  loginStatusCheck = async () => {
    const userToken = await AsyncStorage.getItem('@accessToken');
    if (userToken) {
      this.setState({ isloggedIn: true, loading: false });
    } else {
      this.setState({ isloggedIn: false, loading: false });
    }
  };

  render() {
    if (this.state.loading) return <ActivityIndicator />;

    return (
      <AppContext.Provider
        value={{
          isloggedIn: this.state.isloggedIn,
          setLoggedIn: this.setLoggedIn,
        }}>
        <NavigationContainer>
          {this.state.isloggedIn ? <HomeStackScreen /> : <AuthStackScreen />}
        </NavigationContainer>
      </AppContext.Provider>
    );
  }
}

希望这会有所帮助。

【讨论】:

  • 我用的那个,但是问题出在我的Sign In组件上,我不能用this.props.navigation.navigate('Home'),它给出了错误。
  • 您应该使用回调函数更新应用程序组件中的状态变量,然后您根本不必担心导航
  • 太棒了!这有很大帮助。我欠你一个汉堡:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-08
  • 2021-03-04
  • 1970-01-01
  • 1970-01-01
  • 2017-07-12
  • 2022-07-23
  • 1970-01-01
相关资源
最近更新 更多