Je travaille avec react-navigation v3 et je souhaite utiliser AsyncStorage dans createBottomTabNavigator pour vérifier si l'utilisateur est connecté.
Je sauvegarde la clé dans Stoage dans LoginScreen:
const TabStack = createBottomTabNavigator( { Home: { screen: HomeScreen, }, // I need isLogged key from AsyncStorage here! ...(false ? { Account: { screen: AccountScreen, } } : { Login: { screen: LoginScreen, } }), }, { initialRouteName: 'Home', } );
Et je veux utiliser AsyncStorage dans ma pile (TabStack):
await AsyncStorage.setItem('@MyStorage:isLogged', isLogged);
Comment puis-je le faire?
Mon environnement: strong >
3 Réponses :
Vous n'avez pas besoin de faire cela, vous pouvez simplement vérifier si une session est valide dans l'écran de connexion.
Vous devez créer 2 piles, une pour les écrans auth
et votre TabStack pour les utilisateurs connectés
:
class LoginScreen extends Component { componentDidMount(){ const session = await AsyncStorage.getItem('session'); if (session.isValid) { this.props.navigate('home') } } }
puis vérifiez une session valide dans LoginScreen
dans la méthode componentDidMount
.
const TabStack = createBottomTabNavigator({ Home: { screen: HomeScreen, }, Account: { screen: AccountScreen, } }, { initialRouteName: 'Home', headerMode: 'none', navigationOptions: { headerVisible: false, } }); const stack = createStackNavigator({ Home: {screen: TabStack}, Login: { screen: LoginScreen, } });
Dans votre écran de chargement, lisez votre état de connexion depuis AsyncStorage et stockez-le dans votre magasin Redux (ou tout autre mécanisme de partage de données global de votre choix) - j'utilise redux ici, puis lisez cette donnée dans votre composant Stack comme suit:
import React from "react"; import { View, Text } from "react-native"; import { connect } from "react-redux"; import { createStackNavigator } from "react-navigation"; class Stack extends React.Component { render() { const { isLoggedIn } = this.props.auth; const RouteConfigs = { Home: () => ( <View> <Text>Home</Text> </View> ), Login: () => ( <View> <Text>Login</Text> </View> ) }; const RouteConfigs_LoggedIn = { Home: () => ( <View> <Text>Home</Text> </View> ), Account: () => ( <View> <Text>Account</Text> </View> ) }; const NavigatorConfig = { initialRouteName: "Login" }; const MyStack = createStackNavigator( isLoggedIn ? RouteConfigs_LoggedIn : RouteConfigs, NavigatorConfig ); return <MyStack />; } } const mapStateToProps = ({ auth }) => ({ auth }); export default connect(mapStateToProps)(Stack);
Cela n'a pas fonctionné pour moi, mais en utilisant createAppContainer sur MyStack a fonctionné!
La solution est la suivante: créez un nouveau composant AppTabBar et définissez-le dans la propriété tabBarComponent
export default class AppTabBar extends Component { constructor(props) { super(props); this.state = { isLogged: '0', }; } componentDidMount() { this._retrieveData(); } _retrieveData = async () => { try { const value = await AsyncStorage.getItem('isLogged'); if (value !== null) { this.setState({ isLogged: value, }); } } catch (error) { // Error retrieving data } }; render() { const { navigation, appState } = this.props; const routes = navigation.state.routes; const { isLogged } = this.state; return ( <View style={styles.container}> {routes.map((route, index) => { if (isLogged === '1' && route.routeName === 'Login') { return null; } if (isLogged === '0' && route.routeName === 'Account') { return null; } return ( <View /> // here your tabbar component ); })} </View> ); } navigationHandler = name => { const { navigation } = this.props; navigation.navigate(name); }; }
Et le composant AppTabBar:
const TabStack = createBottomTabNavigator({ Home: { screen: HomeScreen, }, Account: { screen: AccountScreen, } }, { initialRouteName: 'Home', tabBarComponent: AppTabBar, // Here });
apprécions beaucoup la réponse détaillée.