Проблема с загрузкой кнопки в зависимости от состояния входа - PullRequest
0 голосов
/ 17 февраля 2020

Я пытаюсь по-разному отображать условную кнопку в зависимости от состояния аттестации, но продолжаю сталкиваться с проблемами. У меня есть приложение. js, которое определяет stacknavigator, который добавляет кнопку к заголовку, дающую возможность выхода из системы при аутентификации.
Я написал функцию handleLogout, которая должна выполнить это.

import React from 'react';
import { Button, Image, View, Text } from 'react-native';
import firebase from 'react-native-firebase';
import Loading from './Loading';
import SignUp from './SignUp';
import Login from './Login';
import Main from './Main';
import {createAppContainer} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';
import { useNavigation } from '@react-navigation/native';

// eslint-disable-next-line no-undef
handleLogOut = () => {
  const navigation = useNavigation();
  firebase
    .auth()
    .signOut()
    .then(() => this.props.navigation.navigate('Login'))
    .catch(error => this.setState({errorMessage: error.message}));
};

const AppNavigator = createStackNavigator(
  {
    Loading: Loading,
    SignUp: SignUp,
    Login: Login,
    Main: Main,
  },
  {
    initialRouteName: 'Loading',

    defaultNavigationOptions: {
      headerLeft: null,
      headerRight: () => {
          let button = this.loggedIn? (
          <Button
          onPress={this.handleLogOut}
          title="Log-out"
          color="#fff"
          />
        )
        : 
        (
          <Button
          onPress={() => alert('Please log in')}
          title="Log-in"
          color="#fff"
          />
        )
          return button;
      },

      headerStyle: {
        backgroundColor: '#c6f1e7',
      },
      headerTintColor: '#59616e',
      headerTitleStyle: {
        fontFamily: 'Raleway-Regular',
        fontWeight: '400',
      },
    },
  },
);

export default createAppContainer(AppNavigator);

App. js вызывает при загрузке. js, где объявляется значение для входа в систему на основе состояния аутентификации, а затем загружается либо main. js, либо регистрация. в этом случае загружается главная страница, что означает, что кто-то аутентифицирован:

// Loading.js
import React from 'react';
import {View, ActivityIndicator, StyleSheet} from 'react-native';
import firebase from 'react-native-firebase';

export default class Loading extends React.Component {
  componentDidMount() {
    firebase.auth().onAuthStateChanged(user => {
      if (user) {
        this.setState({ loggedIn: true })
        this.props.navigation.navigate(user ? 'Main' : 'SignUp');
      } else {
        this.setState({ loggedIn: false })
      }
    });
  }
  render() {
    return (
      <View style={styles.container}>
        <ActivityIndicator size="large" />
      </View>
    );
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#c6f1e7',
  },
});

Теперь страница перенаправляется на главную и показывает приветственное сообщение, которое указывает, что пользователь вошел в систему, но кнопка в заголовок также говорит «вход в систему», что означает, что кнопка выбрана неправильно. Я предполагаю, что это потому, что значение loggedin не читается, и оно автоматически устанавливает его в loggedin: false.

Вот код для main. js

// Main.js
import React from 'react';
import { View, Text, StyleSheet, Button } from 'react-native';
import firebase from 'react-native-firebase';
import { createAppContainer } from 'react-navigation';
import { createBottomTabNavigator } from 'react-navigation-tabs';
import Kowops from './Kowops';
import Scan from './Scan';
import Wallet from './Wallet';

export class Main extends React.Component {
  state = { currentUser: null }
  componentDidMount() {
    const { currentUser } = firebase.auth()
    this.setState({ currentUser })
}
  render() {
    const { currentUser } = this.state

  return (
      <View style={styles.container}>
        <Text>
          Hidiho {currentUser && currentUser.email}!
        </Text>
      </View>
    )
  }
}
 const bottomTabNavigator = createBottomTabNavigator(
  {
    Main: {screen: Main},
    Kowops: {screen:Kowops},
    Scan: {screen:Scan},
    Wallet: {screen:Wallet},
  },
  {
    //initialRouteName: 'Main',
    tabBarOptions: {
      initialRouteName: 'Main',
      activeTintColor: '#59616e',
      inactiveTintColor: '#a9a9a9',
      style: {
        backgroundColor: '#c6f1e7',
     }
    },
  });

export default createAppContainer(bottomTabNavigator);

const styles = StyleSheet.create({
    container: {
      flex: 1,
      justifyContent: 'center',
      alignItems: 'center',
    }
  }) 

Так что мне нужно чтобы выяснить, как убедиться, что значение isloggedin правильно прочитано и скрипт загружает правую кнопку.

У кого-нибудь есть подсказка?

Заранее спасибо !!

Тим

1 Ответ

2 голосов
/ 17 февраля 2020

Ключевым моментом здесь является то, что вы не можете использовать состояние для разных компонентов, не передавая их в качестве реквизита или через параметры навигации в этом случае. Вы не можете использовать ловушку useNavigation вне функционального компонента, поэтому вы должны передавать объект навигации, когда он вам нужен вне компонента (handleLogout не является компонентом).

Вот некоторые изменения, которые я хотел бы сделать Однако я хотел бы предложить вам внести дополнительные изменения, основываясь на идее, что вы можете использовать навигационные параметры для передачи информации между экранами. Подробнее здесь https://reactnavigation.org/docs/en/params.html.

Приложение. js

DefaultNavigationOptions может быть функцией, которая имеет навигационную опору, это объект навигации, который вы можете использовать для получить параметры или перейти в контексте маршрутизатора.

удалить это исключение eslint, потому что оно вам не нужно, просто правильно объявите переменную. Удалите «this» из вашего вызова функции handleLogout, поскольку он не является атрибутом класса. Используйте navigation.getParam, чтобы получить переменную isLoggedIn, которую вы можете передать в вызове функции навигации.

const handleLogout = navigation => {
    firebase
        .auth()
        .signOut()
        .then(() => navigation.navigate('Login'))
        .catch(error => this.setState({errorMessage: error.message}));
}

...

defaultNavigationOptions: ({navigation}) => ({
    headerRight: () => {

        const isLoggedIn = navigation.getParam('isLoggedIn', false);
        let button = isLoggedIn ? (
          <Button
            onPress={() => handleLogOut(navigation)}
            title="Log-out"
            color="#fff"
          />
        ) : ...
    } ...

Сейчас загружается. js Здесь вам нужно добавить параметр навигации к вашему вызову навигации, который затем может быть используется в заголовке

 ...
 firebase.auth().onAuthStateChanged(user => {
  if (user) {

    this.props.navigation.navigate('Main', {isLoggedIn: true});
  } else {
    this.props.navigation.navigate('SignUp', {isLoggedIn: false});
  }
});    

вот модифицированная версия вашего кода в виде закуски, которая, как вы видите, получит зарегистрированный параметр и покажет кнопку выхода из системы https://snack.expo.io/@dannyhw / intrigued-graham-crackers Вам потребуется внести дополнительные изменения, чтобы исправить другие функции, потому что я изменил только минимум, чтобы показать, что вы можете использовать параметр навигации.

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