Reaccionar-navegación con pantalla de conexión

votos
43

Estoy tratando de utilizar reaccionar navegación para crear una pantalla de inicio de sesión inicial que no tiene barra de pestañas y la cabecera, y una vez que el usuario ha sido autenticado con éxito navegará a otra pantalla llamada LISTRECORD que tiene una barra de pestañas, cabecera y sin opción de botón de retroceso. Alguien tiene experiencia en esto y puede compartir?

En resumen, lo que estoy tratando de lograr con reaccionan de navegación se describe a continuación ...

Pantalla 1: pantalla de inicio de sesión (n Encabezado y Tabbar)
autenticado ...
Pantalla 2: LISTRECORD (Cabecera, y Tabbar Ningún botón Atrás)
La barra de pestañas contiene otras pestañas también para la navegación a pantalla 3, pantalla de 4 ...

Publicado el 18/03/2017 a las 13:09
fuente por usuario
En otros idiomas...                            


11 respuestas

votos
2

Hacer barra de pestañas y la cabecera de componentes separados y sólo los incluyen en otros componentes. Acerca de la inhabilitación "BACK", hay una sección de "acciones de bloqueo de navegación" en la documentación: https://reactnavigation.org/docs/routers/

Usted debe ser capaz de utilizar que para la pantalla 2.

Respondida el 27/03/2017 a las 17:17
fuente por usuario

votos
12

así es como me Achived esta funcionalidad.

Presentar 0) index.android.js

'use strict'

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View
} from 'react-native';

import Root from 'src/containers/Root'


AppRegistry.registerComponent('Riduk', () => Root);

1) presentar mis Root.js

class Root extends Component {
    constructor(props) {
      super(props);
      this.state = {
        authenticated:false,
        isLoading:true,
        store: configureStore(() => this.setState({isLoading: false})),
      };
  }

  componentDidMount() {
    //you can do check with authentication with fb, gmail and other right here
   /* firebase.auth().onAuthStateChanged((user) => {
      if (user) {
        api.resetRouteStack(dispatch, "UserProfile");
        console.log("authenticated", user);
      } else {
        api.resetRouteStack(dispatch, "Landing");
        console.log("authenticated", false);
      }
    });*/

  }

  render() {
    if (this.state.isLoading) {  //checking if the app fully loaded or not, splash screen can be rendered here
        return null;
      }
      return (

        <Provider store={this.state.store}>
          <App/>
        </Provider>

      );
  }
}
module.exports = Root;

2) app.js

import AppWithNavigationState,{AppBeforeLogin} from './AppNavigator';

class App extends Component{
    constructor(props){
        super(props);
    }

    render(){
        let {authenticated} = this.props;
        if(authenticated){
            return <AppWithNavigationState/>;
        }
        return <AppBeforeLogin/>


    }
}

export default connect(state =>({authenticated: state.user.authenticated}))(App);

3) AppNavigator.js

'use strict';

import React, {Component} from 'react';
import { View, BackAndroid, StatusBar,} from 'react-native';
import {
  NavigationActions,
  addNavigationHelpers,
  StackNavigator,
} from 'react-navigation';
import { connect} from 'react-redux';

import LandingScreen from 'src/screens/landingScreen';
import Login from 'src/screens/login'
import SignUp from 'src/screens/signUp'
import ForgotPassword from 'src/screens/forgotPassword'
import UserProfile from 'src/screens/userProfile'
import Drawer from 'src/screens/drawer'



const routesConfig = {
  //Splash:{screen:SplashScreen},
  Landing:{screen:LandingScreen},
  Login: { screen: Login },
  SignUp: { screen: SignUp },
  ForgotPassword: { screen: ForgotPassword },
  UserProfile:{screen:UserProfile},
};


export const AppNavigator = StackNavigator(routesConfig, {initialRouteName:'UserProfile'}); //navigator that will be used after login

const exportación AppBeforeLogin = StackNavigator (routesConfig); // naviagtor para antes de inicio de sesión

class AppWithNavigationState extends Component{
  constructor(props) {
    super(props);
    this.handleBackButton = this.handleBackButton.bind(this);
  }

  componentDidMount() {
    BackAndroid.addEventListener('hardwareBackPress', this.handleBackButton);
  }

  componentWillUnmount() {
    BackAndroid.removeEventListener('hardwareBackPress', this.handleBackButton);
  }

  //added to handle back button functionality on android
  handleBackButton() {
    const {nav, dispatch} = this.props;

    if (nav && nav.routes && nav.routes.length > 1) {
      dispatch(NavigationActions.back());
      return true;
    }
    return false;
  }

  render() {
    let {dispatch, nav} = this.props;

    return (
          <View style={styles.container}>
            {(api.isAndroid()) &&
              <StatusBar
                  backgroundColor="#C2185B"
                  barStyle="light-content"
              />
            }
            <AppNavigator navigation={addNavigationHelpers({ dispatch, state: nav })}/>
          </View>
    );
  }
};
export default connect(state =>({nav: state.nav}))(AppWithNavigationState);
//module.exports = AppWithNavigationState;
Respondida el 28/03/2017 a las 06:02
fuente por usuario

votos
26

A pesar de lo que sugiere Manjeet va a funcionar, no es una buena estructura de navegación.

Lo que debe hacer es dar un paso atrás y manejar todo a otro nivel.

Top Navigator nivel debe ser un navegador de pila que hace que una pantalla de inicio de sesión. Otra pantalla dentro de este top-navegante debe ser más de su aplicación principal-Navigator. Cuando su estado de inicio de sesión es satisfecha, se restablece la chimenea principal a sólo el principal-Navigator.

La razón de esta estructura es:

A- ¿Qué pasa si es necesario agregar en la información de embarque antes de la sesión el futuro?

B- ¿Qué pasa si usted necesita para desplazarse fuera del entorno principal de la navegación (por ejemplo: su navegación por pestañas principal es y desea una visión no-tab)?

Si su navegador de más arriba es un Pila-Navigator que presenta pantallas de acceso y otros navegantes, a continuación, estructura de navegación de su aplicación puede escalar correctamente.

No creo que la prestación condicional de una pantalla de inicio de sesión o la pila de navegador, como se sugirió anteriormente, es una buena idea .... confía en mí ... me he ido por ese camino.

Respondida el 31/03/2017 a las 09:33
fuente por usuario

votos
7

Esta es mi solución basada en la recomendación @parker :

  1. Crear un navegador de nivel superior y que debería ser un navegador de pila que hace que una pantalla de inicio de sesión.
  2. Otra pantalla dentro de este navegador de nivel superior debe ser de su aplicación principal-Navigator.
  3. Cuando su estado de inicio de sesión es satisfecha, se restablece la chimenea principal a sólo el principal-Navigator.

Este código hace lo mínimo para lograr lo anterior.

Crear un nuevo proyecto reaccionar-natal, a continuación, copie el siguiente código en index.ios.js y / o index.android.js para ver su funcionamiento.

import React, { Component } from 'react';
import {
  AppRegistry,
  Text,
  Button
} from 'react-native';
import { StackNavigator, NavigationActions } from 'react-navigation';

const resetAction = NavigationActions.reset({
  index: 0,
  actions: [
    NavigationActions.navigate({ routeName: 'Main' })
  ]
});

class LoginScreen extends Component {
  login() {
    this.props.navigation.dispatch(resetAction);
  }

  render() {
    return <Button title='Login' onPress={() => {this.login()}} />;
  }
}

class FeedScreen extends Component {
  render() {
    return <Text>This is my main app screen after login</Text>;
  }
}

//Create the navigation
const MainNav = StackNavigator({
    Feed: { screen: FeedScreen },
});

const TopLevelNav = StackNavigator({
  Login: { screen: LoginScreen },
  Main: { screen: MainNav },
}, {
  headerMode: 'none',
});


AppRegistry.registerComponent('ReactNav2', () => TopLevelNav);
Respondida el 26/05/2017 a las 19:31
fuente por usuario

votos
3

Es bueno que está utilizando reaccionar navegación que tiene un buen soporte para la mayoría de las características de su aplicación requiere. Aquí está mi consejo

1) En la autenticación

Reaccionar nativo tiene esta característica agradable variables de estado que cuando se cambiaron vistas son re-renderizados. Puede utilizar variables de estado para entender el "estado" (autenticado / visitante) de los usuarios de su aplicación.

Aquí es una aplicación sencilla en la que un usuario inicia sesión pulsando un botón de inicio de sesión

página de entrada, donde los registros de usuario en

import React from 'react';

import Home from './layouts/users/home/Home';
import Login from './layouts/public/login/Login';


class App extends React.Component {

    state = {
        isLoggedIn: false
      }

    componentDidMount() {
        //Do something here like hide splash screen
    }

    render(){
        if (this.state.isLoggedIn)
         return <Home

             />;
     else
         return <Login
         onLoginPress={() => this.setState({isLoggedIn: true})}
             />;

    }
}

export default App;

2) Entrar con la cabecera

Iniciar sesión Ver

import React from 'react';
//Non react-native import
import { TabNavigator } from 'react-navigation'
import Icon from 'react-native-vector-icons/MaterialIcons'
import LoginStyles from './Style'
//Do all imports found in react-native here
import {
    View,
    Text,
    TextInput,
    StyleSheet,
    TouchableOpacity,
} from 'react-native';


class Login extends React.Component {
  render(){

         return (
       <View>
       <Text>
         Login area
       </Text>

       <TouchableOpacity
                style={LoginStyles.touchable}
                onPress={this.props.onLoginPress}   >

                <Text style={LoginStyles.button}>
               Login
                </Text>
                </TouchableOpacity>



       </View>
     );

    }
}

export default Login;

Recuerde que debe eliminar los atributos de estilo en la pantalla de inicio de sesión y agrega el tuyo incluyendo la importación, yo los dejo allí, ya que puede ayudar a tener y la idea de cómo se puede organizar reaccionas proyecto

Sin embargo, todavía funciona sin los estilos para que pueda quitárselos, haga clic en el botón de inicio de sesión le llevará a la pantalla de inicio, ya que el estado cambiado y la vista tiene que ser re-renderizados según un nuevo estado

La pantalla de inicio de sesión es sin cabecera como que necesita

pantalla de inicio con las pestañas

3) aquí con cabecera El método general para conseguir esta funcionalidad para añadir una TabNavigatoren una StackNavigator.

       import React from 'react';
    import {
     DrawerNavigator,
     StackNavigator,
     TabNavigator,
     TabBarBottom,
     NavigationActions
    } from 'react-navigation'
    import Icon from 'react-native-vector-icons/MaterialIcons'


    //Do all imports found in react-native here
    import {
        View,
        Text,
        TextInput,
        StyleSheet,
        TouchableOpacity,
    } from 'react-native';

class PicturesTab extends React.Component {
  static navigationOptions = {
    tabBarLabel: 'Pictures',
    // Note: By default the icon is only shown on iOS. Search the showIcon option below.
    tabBarIcon: ({ tintColor }) =>  (<Icon size={30} color={tintColor} name="photo" />),
  };

  render() { return <Text>Pictures</Text> }
}

class VideosTab extends React.Component {
  static navigationOptions = {
    tabBarLabel: 'Videos',
    tabBarIcon: ({ tintColor }) =>  (<Icon size={30} color={tintColor} name="videocam" />),
  };

  render() { return <Text>Videos</Text> }

}

    const HomeTabs = TabNavigator({
      Pictures: {
        screen: PicturesTab,
      },
      Videos: {
        screen: VideosTab,
      },
    }, {
        tabBarComponent: TabBarBottom,
        tabBarPosition: 'bottom',
        tabBarOptions: {
        //Thick teal #094545
        activeTintColor: '#094545',
        showLabel: false,
        activeBackgroundColor: '#094545',
        inactiveTintColor: '#bbb',
        activeTintColor: '#fff',


      }
    });



    const HomeScreen = StackNavigator({
      HomeTabs : { screen: HomeTabs,
        navigationOptions: ({ navigation }) => ({
        // title :'title',
        // headerRight:'put some component here',
        // headerLeft:'put some component here',
         headerStyle: {
           backgroundColor: '#094545'
         }


       })
     },
    });




    export default HomeScreen;

Exención de responsabilidad: Código puede devolver errores, ya que algunos archivos pueden ser falta o algunos errores ortográficos puede estar presente usted debe comprobar los detalles con cuidado y cambiar el lugar donde NECESARIO si tiene que copiar el código. Cualquier problema se puede pegar como comentarios. Espero que esto ayude a alguien.

También puede eliminar los iconos de las configuraciones de la ficha o instalar los iconos reaccionar nativo-vector que hace que las pestañas grandes!

Respondida el 27/05/2017 a las 22:56
fuente por usuario

votos
33

Oct 2017 me encontré con este ridículamente confusos, así que aquí está mi solución empezando de arriba hacia abajo:

Yo recomiendo empezar un nuevo proyecto y, literalmente, sólo pegar todo esto en el estudio y después. Comenté el gran código de tiempo, por lo que si usted está atascado en cualquier área específica, tal vez el contexto puede ayudar a volver a la pista.

Este post muestra cómo:

  1. Reaccionar completamente configurada para funcionar nativo reaccionar navegación
  2. Adecuadamente la integración con Redux
  3. Android manejar el botón trasero
  4. Jerarquía de la pila Navegadores
  5. Navegar desde niño a navegantes para padres
  6. Restablecer la pila de navegación
  7. Restablecer la pila de navegación durante la navegación de hijo a padre (anidada)

index.js

import { AppRegistry } from 'react-native'
import App from './src/App'

AppRegistry.registerComponent('yourappname', () => App)

src / app.js (este es el archivo más importante, ya que aporta todos los pedazos juntos)

import React, { Component } from 'react'
// this will be used to make your Android hardware Back Button work
import { Platform, BackHandler } from 'react-native'
import { Provider, connect } from 'react-redux'
import { addNavigationHelpers } from 'react-navigation'
// this is your root-most navigation stack that can nest
// as many stacks as you want inside it
import { NavigationStack } from './navigation/nav_reducer'
// this is a plain ol' store
// same as const store = createStore(combinedReducers)
import store from './store'

// this creates a component, and uses magic to bring the navigation stack
// into all your components, and connects it to Redux
// don't mess with this or you won't get
// this.props.navigation.navigate('somewhere') everywhere you want it
// pro tip: that's what addNavigationHelpers() does
// the second half of the critical logic is coming up next in the nav_reducers.js file
class App extends Component {
    // when the app is mounted, fire up an event listener for Back Events
    // if the event listener returns false, Back will not occur (note that)
    // after some testing, this seems to be the best way to make
    // back always work and also never close the app
    componentWillMount() {
        if (Platform.OS !== 'android') return
        BackHandler.addEventListener('hardwareBackPress', () => {
            const { dispatch } = this.props
            dispatch({ type: 'Navigation/BACK' })
            return true
        })
    }

    // when the app is closed, remove the event listener
    componentWillUnmount() {
        if (Platform.OS === 'android') BackHandler.removeEventListener('hardwareBackPress')
    }

    render() {
        // slap the navigation helpers on (critical step)
        const { dispatch, nav } = this.props
        const navigation = addNavigationHelpers({
            dispatch,
            state: nav
        })
        return <NavigationStack navigation={navigation} />
    }
}

// nothing crazy here, just mapping Redux state to props for <App />
// then we create your root-level component ready to get all decorated up
const mapStateToProps = ({ nav }) => ({ nav })
const RootNavigationStack = connect(mapStateToProps)(App)

const Root = () => (
    <Provider store={store}>
        <RootNavigationStack />
    </Provider>
)

export default Root

src / navegación / nav_reducer.js

// NavigationActions is super critical
import { NavigationActions, StackNavigator } from 'react-navigation'
// these are literally whatever you want, standard components
// but, they are sitting in the root of the stack
import Splash from '../components/Auth/Splash'
import SignUp from '../components/Auth/SignupForm'
import SignIn from '../components/Auth/LoginForm'
import ForgottenPassword from '../components/Auth/ForgottenPassword'
// this is an example of a nested view, you might see after logging in
import Dashboard from '../components/Dashboard' // index.js file

const WeLoggedIn = StackNavigator({
    LandingPad: {             // if you don't specify an initial route,
        screen: Dashboard     // the first-declared one loads first
    }
}, {
    headerMode: 'none'
    initialRouteName: LandingPad // if you had 5 components in this stack,
})                               // this one would load when you do
                                 // this.props.navigation.navigate('WeLoggedIn')

// notice we are exporting this one. this turns into <RootNavigationStack />
// in your src/App.js file.
export const NavigationStack = StackNavigator({
    Splash: {
        screen: Splash
    },
    Signup: {
        screen: SignUp
    },
    Login: {
        screen: SignIn
    },
    ForgottenPassword: {
        screen: ForgottenPassword
    },
    WeLoggedIn: {
        screen: WeLoggedIn  // Notice how the screen is a StackNavigator
    }                       // now you understand how it works!
}, {
    headerMode: 'none'
})

// this is super critical for everything playing nice with Redux
// did you read the React-Navigation docs and recall when it said
// most people don't hook it up correctly? well, yours is now correct.
// this is translating your state properly into Redux on initialization    
const INITIAL_STATE = NavigationStack.router.getStateForAction(NavigationActions.init())

// this is pretty much a standard reducer, but it looks fancy
// all it cares about is "did the navigation stack change?"    
// if yes => update the stack
// if no => pass current stack through
export default (state = INITIAL_STATE, action) => {
    const nextState = NavigationStack.router.getStateForAction(action, state)

    return nextState || state
}

src / Tienda / index.js

// remember when I said this is just a standard store
// this one is a little more advanced to show you
import { createStore, compose, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import { persistStore, autoRehydrate } from 'redux-persist'
import { AsyncStorage } from 'react-native'
// this pulls in your combinedReducers
// nav_reducer is one of them
import reducers from '../reducers'

const store = createStore(
    reducers,
    {},
    compose(
        applyMiddleware(thunk),
        autoRehydrate()
    )
)

persistStore(store, { storage: AsyncStorage, whitelist: [] })

// this exports it for App.js    
export default store

src / reducers.js

// here is my reducers file. i don't want any confusion
import { combineReducers } from 'redux'
// this is a standard reducer, same as you've been using since kindergarten
// with action types like LOGIN_SUCCESS, LOGIN_FAIL
import loginReducer from './components/Auth/login_reducer'
import navReducer from './navigation/nav_reducer'

export default combineReducers({
    auth: loginReducer,
    nav: navReducer
})

src / componentes / auth / SignUpForm.js

Yo te mostraré una muestra aquí. Esto no es mío, me acaba de escribir hacia fuera para usted en este editor Stackoverflow raquítica. Por favor, dame los pulgares para arriba si usted lo aprecia :)

import React, { Component } from 'react'
import { View, Text, TouchableOpacity } from 'react-native

// notice how this.props.navigation just works, no mapStateToProps
// some wizards made this, not me
class SignUp extends Component {
    render() {
        return (
            <View>
                <Text>Signup</Text>
                <TouchableOpacity onPress={() => this.props.navigation.navigate('Login')}>
                    <Text>Go to Login View</Text>
                </TouchableOpacity>
            </View>
        )
    }
}

export default SignUp

src / componentes / auth / LoginForm.js

Te voy a mostrar un solo estilo tonto también, con el aditivo súper botón de retroceso

import React from 'react'
import { View, Text, TouchableOpacity } from 'react-native

// notice how we pass navigation in
const SignIn = ({ navigation }) => {
    return (
        <View>
            <Text>Log in</Text>
            <TouchableOpacity onPress={() => navigation.goBack(null)}>
                <Text>Go back to Sign up View</Text>
            </TouchableOpacity>
        </View>
    )
}

export default SignIn

src / componentes / auth / Splash.js

Aquí está una pantalla de bienvenida se puede jugar. Lo estoy usando como un componente de orden superior:

import React, { Component } from 'react'
import { StyleSheet, View, Image, Text } from 'react-native'
// https://github.com/oblador/react-native-animatable
// this is a library you REALLY should be using
import * as Animatable from 'react-native-animatable' 
import { connect } from 'react-redux'
import { initializeApp } from './login_actions'

class Splash extends Component {
    constructor(props) {
        super(props)
        this.state = {}
    }

    componentWillMount() {
        setTimeout(() => this.props.initializeApp(), 2000)
    }

    componentWillReceiveProps(nextProps) {
        // if (!nextProps.authenticated) this.props.navigation.navigate('Login')
        if (nextProps.authenticated) this.props.navigation.navigate('WeLoggedIn')
    }

    render() {
        const { container, image, text } = styles
        return (
            <View style={container}>
                    <Image
                        style={image}
                        source={require('./logo.png')}
                    />

                    <Animatable.Text
                        style={text}
                        duration={1500}
                        animation="rubberBand"
                        easing="linear"
                        iterationCount="infinite"
                    >
                        Loading...
                    </Animatable.Text>
                    <Text>{(this.props.authenticated) ? 'LOGGED IN' : 'NOT LOGGED IN'}</Text>
            </View>
        )
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F0F0F0'
    },
    image: {
        height: 110,
        resizeMode: 'contain'
    },
    text: {
        marginTop: 50,
        fontSize: 15,
        color: '#1A1A1A'
    }
})

// my LOGIN_SUCCESS action creator flips state.auth.isAuthenticated to true    
// so this splash screen just watches it
const mapStateToProps = ({ auth }) => {
    return {
        authenticated: auth.isAuthenticated
    }
}

export default connect(mapStateToProps, { initializeApp })(Splash)

src / componentes / auth / login_actions.js

Sólo voy a mostrar initializeApp () para que pueda obtener algunas ideas:

import {
    INITIALIZE_APP,
    CHECK_REMEMBER_ME,
    TOGGLE_REMEMBER_ME,
    LOGIN_INITIALIZE,
    LOGIN_SUCCESS,
    LOGIN_FAIL,
    LOGOUT
} from './login_types'

//INITIALIZE APP
// this isn't done, no try/catch and LOGIN_FAIL isn't hooked up
// but you get the idea
// if a valid JWT is detected, they will be navigated to WeLoggedIn
export const initializeApp = () => {
    return async (dispatch) => {
        dispatch({ type: INITIALIZE_APP })

        const user = await AsyncStorage.getItem('token')
            .catch((error) => dispatch({ type: LOGIN_FAIL, payload: error }))

        if (!user) return dispatch({ type: LOGIN_FAIL, payload: 'No Token' })

        return dispatch({
            type: LOGIN_SUCCESS,
            payload: user
        })
        // navigation.navigate('WeLoggedIn')
        // pass navigation into this function if you want
    }
}

En otros casos de uso, es posible que prefiera el componente de orden superior. Funcionan exactamente igual que Reaccionar para la web. tutoriales de Stephen Grider en Udemy son los mejores, y punto.

src / ESPECIAL / require_auth.js

import React, { Component } from 'react'
import { connect } from 'react-redux'

export default function (ComposedComponent) {
    class Authentication extends Component {

        componentWillMount() {
            if (!this.props.authenticated) this.props.navigation.navigate('Login')
        }

        componentWillUpdate(nextProps) {
            if (!nextProps.authenticated) this.props.navigation.navigate('Login')
        }

        render() {
            return (
                <ComposedComponent {...this.props} />
            )
        }
    }

    const mapStateToProps = ({ auth }) => {
        return {
            authenticated: auth.isAuthenticated
        }
    }

    return connect(mapStateToProps)(Authentication)
}

Que lo utilice como este:

import requireAuth from '../HOC/require_auth'

class RestrictedArea extends Component {
    // ... normal view component
}

//map state to props

export default connect(mapStateToProps, actions)(requireAuth(RestrictedArea))

No, esto es todo lo que me gustaría que alguien dijo y me mostró.

TLDR El App.js, ynav_reducer.js los archivos son absolutamente el más importante para hacerlo bien. El resto es viejo y conocido. Mis ejemplos que deben acelerar la productividad en una máquina salvaje.

[Editar] Aquí está mi creador acción de cierre de sesión. Usted encontrará que es muy útil si desea limpiar su pila de navegación por lo que el usuario no puede pulsar el botón trasero del hardware Android y volver a una pantalla que requiere autenticación:

//LOGOUT
export const onLogout = (navigation) => {
    return async (dispatch) => {
        try {
            await AsyncStorage.removeItem('token')

            navigation.dispatch({
                type: 'Navigation/RESET',
                index: 0,
                actions: [{ type: 'Navigate', routeName: 'Login' }]
            })

            return dispatch({ type: LOGOUT })
        } catch (errors) {
            // pass the user through with no error
            // this restores INITIAL_STATE (see login_reducer.js)
            return dispatch({ type: LOGOUT })
        }
    }
}

// login_reducer.js
    case LOGOUT: {
        return {
            ...INITIAL_STATE,
            isAuthenticated: false,
        }
    }

[Bonificación editar] ¿Cómo navegar de un niño Pila Navigator para un padre Pila Navigator?

Si desea navegar de uno de sus hijos Pila navegantes y restablecer la pila, haga lo siguiente:

  1. Estar dentro de un código de adición de componentes, donde se tiene this.props.navigation a disposición
  2. Hacer un componente como <Something />
  3. Pasar la navegación en él, como este: <Something navigation={this.props.navigation} />
  4. Entrar en el código de ese componente
  5. Note que tiene this.props.navigation disponible dentro de este componente del niño
  6. Ahora ya está, acaba de llamar this.props.navigation.navigate('OtherStackScreen')y usted debe ver Reaccionar nativo mágicamente ir allí sin problema

Pero, quiero RESTABLECER toda la pila mientras se navega a una pila de los padres.

  1. Llame a un creador de acción o algo así (partiendo desde el paso 6): this.props.handleSubmit(data, this.props.navigation)
  2. Entra en el creador de acción y observar el código que podría estar allí:

actionCreators.js

// we need this to properly go from child to parent navigator while resetting
// if you do the normal reset method from a child navigator:
this.props.navigation.dispatch({
    type: 'Navigation/RESET',
    index: 0,
    actions: [{ type: 'Navigate', routeName: 'SomeRootScreen' }]
})

// you will see an error about big red error message and
// screen must be in your current stack 
// don't worry, I got your back. do this
// (remember, this is in the context of an action creator):
import { NavigationActions } from 'react-navigation'

// notice how we passed in this.props.navigation from the component,
// so we can just call it like Dan Abramov mixed with Gandolf
export const handleSubmit = (token, navigation) => async (dispatch) => {
    try {
        // lets do some operation with the token
        await AsyncStorage.setItem('token@E1', token)
        // let's dispatch some action that doesn't itself cause navigation
        // if you get into trouble, investigate shouldComponentUpdate()
        // and make it return false if it detects this action at this moment
        dispatch({ type: SOMETHING_COMPLETE })

        // heres where it gets 100% crazy and exhilarating
        return navigation.dispatch(NavigationActions.reset({
            // this says put it on index 0, aka top of stack
            index: 0,
            // this key: null is 9001% critical, this is what
            // actually wipes the stack
            key: null,
            // this navigates you to some screen that is in the Root Navigation Stack
            actions: [NavigationActions.navigate({ routeName: 'SomeRootScreen' })]
        }))
    } catch (error) {
        dispatch({ type: SOMETHING_COMPLETE })
        // User should login manually if token fails to save
        return navigation.dispatch(NavigationActions.reset({
            index: 0,
            key: null,
            actions: [NavigationActions.navigate({ routeName: 'Login' })]
        }))
    }
}

Estoy utilizando este código dentro de un nivel empresarial Reaccionar aplicación nativa, y funciona muy bien.

react-navigationes como la programación funcional. Está diseñado para ser manejado en pequeños fragmentos "pura" de navegación que componen bien juntos. Si usted emplea la estrategia descrita anteriormente, se encontrará la creación de re-utilizable lógica de navegación que sólo puede pegar en todo lo necesario.

Respondida el 13/10/2017 a las 05:37
fuente por usuario

votos
-2

Sé que estoy viejo aquí, pero este artículo salvó mi culo, estoy en el infierno con la navegación y ahora me siento más cómodo.

Ese tipo es explicar la API interna que le permite construir su navegación como exactamente como te imaginas , usando un navegador principal pila también.

Que se adentra con un ejemplo de autenticación

https://hackernoon.com/a-comprehensive-guide-for-integrating-react-navigation-with-redux-including-authentication-flow-cb7b90611adf

Por favor aplaudir este tipo :-)

Respondida el 21/02/2018 a las 07:06
fuente por usuario

votos
1

react-navigationahora tiene una SwitchNavigatorque ayuda comportamiento deseado y la conmutación entre los navegantes. Actualmente no hay mucha documentación al respecto, pero hay un muy buen ejemplo de aperitivos creado por la biblioteca que muestra una implementación simple flujo de autenticación. Puede comprobarlo aquí .

referencia SwitchNavigator

SwitchNavigator(RouteConfigs, SwitchNavigatorConfig)

Ejemplo de docs

const AppStack = StackNavigator({ Home: HomeScreen, Other: OtherScreen });
const AuthStack = StackNavigator({ SignIn: SignInScreen });

export default SwitchNavigator(
  {
    AuthLoading: AuthLoadingScreen,
    App: AppStack,
    Auth: AuthStack,
  },
  {
    initialRouteName: 'AuthLoading',
  }
);
Respondida el 10/04/2018 a las 05:37
fuente por usuario

votos
0

En la actualidad existe una buena documentación en el sitio reaccionar-Naviation sobre el flujo de autenticación .

Respondida el 22/05/2018 a las 16:58
fuente por usuario

votos
0

Si desea ningún botón de vuelta de la página de lista a la página de acceso, se puede hacer esto:

    static navigationOptions = {
        title: 'YOUR TITLE',
        headerLeft : null,
    };
Respondida el 18/06/2018 a las 11:23
fuente por usuario

votos
0

Necesitaba esto, pero ninguna de las otras soluciones trabajó para mí. Así que aquí está mi solución para una sesión con un cajón (esta última accesible sólo después de la autenticación correcta, y cada una de las pantallas en el interior tienen su propio pila de navegación). Mi código tiene una DrawerNavigator, pero lo mismo se podría utilizar para una TabNavigator (createBottomTabNavigator).

wrapScreen = stackNavigator =>
  createStackNavigator(stackNavigator, {
    defaultNavigationOptions: ({ navigation }) => ({
      headerStyle: { backgroundColor: "white" },
      headerLeft: MenuButton(navigation)
    })
  });

const DrawerStack = createDrawerNavigator(
  {
    // Menu Screens
    firstSection: wrapScreen({ FirstScreen: FirstScreen }),
    secondSection: wrapScreen({
      SecondHomeScreen: SecondHomeScreen,
      SecondOptionScreen: SecondOptionScreen
    }),
    settingSection: wrapScreen({ SettingScreen: SettingScreen }),
    aboutSection: wrapScreen({ AboutScreen: AboutScreen })
  },
  {
    initialRouteName: "firstSection",
    gesturesEnabled: false,
    drawerPosition: "left",
    contentComponent: DrawerContainer
  }
);

const PrimaryNav = createSwitchNavigator(
  {
    loginStack: LoginScreen,
    appStack: DrawerStack
  },
  { initialRouteName: "loginStack" }
);

export default createAppContainer(PrimaryNav);

Espero que pueda ayudar a otros.

Respondida el 14/12/2018 a las 14:43
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more