Объедините React Navigation 3.0 и JWT, чтобы определить initialRouteName на основе состояния авторизации - PullRequest
0 голосов
/ 30 ноября 2018

Я пытаюсь заставить нормальный компонент App.js, интегрированный с клиентом JWT, вести себя корректно при интеграции React Navigator 3.0

К сожалению, я могу заставить работать только один или другой, но не оба.Моя проблема заключается в том, что React Navigator как бы перехватывает App.js и определяет начальный маршрут вместо обычного рендера компонента приложения.

Вот мой код:

App.js

import React, { Component } from 'react';
import { createAppContainer,
         createBottomTabNavigator,
        } from 'react-navigation';
import Auth from './src/screens/Auth';
import HomeScreen from './src/screens/HomeScreen';

class App extends Component {
  constructor() {
    super();
    this.state = {
      jwt: '',
    };
  }

  render() {
     if (!this.state.jwt) {
      return (
        <Auth />
      );
    } else if (this.state.jwt) {
      return (
        <HomeScreen />
      );
    }
  }
}

const TabNavigator = createBottomTabNavigator({
  Home: { screen: HomeScreen,
          navigationOptions: {
            tabBarLabel: 'Home',
          }
        },
  Auth: { screen: Auth,
          navigationOptions: {
            tabBarLabel: 'Auth',
          }
        },
  },
  { initialRouteName: App.state.jwt ? 'Home' : 'Auth' }
);

export default createAppContainer(TabNavigator);

Как видите, у меня проблема с этой строкой:

{ initialRouteName: App.state.jwt ? 'Home' : 'Auth' }

Как я могу получить состояние JWT внутри компонента TabNavigator, чтобы я мог определить правильное имя initialRouteName?

this.state.jwt и App.state.jwt, очевидно, не работают, и я попытался (и не смог) передать состояние объекту TabNavigator в качестве опоры.

Любая помощь приветствуется.

Ответы [ 2 ]

0 голосов
/ 17 декабря 2018

Могу ли я спросить, что вы включили экран входа для аутентификации?

0 голосов
/ 09 декабря 2018

Это правильный метод:

Сначала вы устанавливаете токен Auth и сохраняете его состояние в App.js.Затем вы передаете состояние как screenProps объекту навигации:

export default class App extends React.Component {

  constructor() {
    super();
    this.state = {
      jwt: '',
      loading: true
    };
    this.newJWT = this.newJWT.bind(this);
    this.deleteJWT = deviceStorage.deleteJWT.bind(this);
    this.loadJWT = deviceStorage.loadJWT.bind(this);
    this.loadJWT();
  }

  state = {
    isLoadingComplete: false,
  };

  newJWT(jwt) {
    this.setState({
      jwt: jwt
    });
  }

  render() {
    if (this.state.loading) {
      return (
        <Loading size={'large'} />
       );
    } else if (!this.state.jwt) {
      return (
        <View style={styles.container}>
          {Platform.OS === 'ios' && <StatusBar barStyle="default" />}
          <TabNavigator screenProps={{setToken: this.newJWT }} />
        </View>
      );
    }

Объект навигации передает его на экраны, которые в нем нуждаются.

const TabNavigator = createMaterialTopTabNavigator(
  {
  Profile: {
    screen: props => <ProfileScreen {...props.screenProps} />,
    navigationOptions: {
        //tabBarLabel: 'Perfil',
        title: 'Header Title',
        tabBarIcon: ({ tintColor, focused }) => (
      <Ionicons
        name={focused ? 'ios-person' : 'ios-person'} //TODO change to focused icon
        size={26}
        style={{ color: tintColor }}
      />
    ),
  }
  },

A вы можете увидетьреквизиты могут передаваться как ScreenProps, а затем считываться в дочернем компоненте (экране) следующим образом:

export default class ProfileScreen extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: true,
      email: '',
      username: '',
      phone: '',
      password: '',
      name: '',
      error: ''
    };
  }

  componentDidMount() {
    const headers = {
      Authorization: this.props.jwt
    };
    api.get('/user')
    .then((response) => {
      this.setState({
        email: response.data.data.attributes.email,
        phone: response.data.data.attributes.phone,
        username: response.data.data.attributes.username,
        name: response.data.data.attributes.name,
        loading: false
      });
    }).catch((error) => {
      this.setState({
        error: 'Error retrieving data',
        loading: false
      });
    });
  }

Я полагаю, что с Redux это будет намного проще, но я все еще учусь этому.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...