Я получил навигацию как неопределенную в реакции навигации 5?

У меня есть многоразовый компонент для входа с помощью кнопки Apple. После успеха пользователя я перехожу на главный экран.

Но я замечаю, что когда я регистрирую navigation, это не определено,

и когда я регистрирую this.props, я только что получил два действия, которые я сделал в редуксе!

Итак, как я могу получить доступ к навигации в этом компоненте и почему он не доступен по умолчанию!

Журнал

реквизит => {"isLogin": [Function isLogin], "storeToken": [Function storeToken]} навигация => undefined

Код

import appleAuth, {
  AppleAuthCredentialState,
  AppleAuthError,
  AppleAuthRealUserStatus,
  AppleAuthRequestOperation,
  AppleAuthRequestScope,
  AppleButton,
} from '@invertase/react-native-apple-authentication';
import React from 'react';
import {ActivityIndicator, StyleSheet, View} from 'react-native';
import {connect} from 'react-redux';
import API from '../../api/API';
import {isLoginFunc} from '../../redux/actions/isLoginAction';
import {saveToken} from '../../redux/actions/saveTokenAction';

class AppleAuth extends React.Component {
  constructor(props) {
    super(props);
    this.authCredentialListener = null;
    this.user = null;
    this.state = {
      credentialStateForUser: -1,
      loading: false,
    };
  }
  componentDidMount() {
    const {navigation} = this.props;
    console.log('did-navigation', navigation);
    console.log('did- this.props', this.props);
    /**
     * subscribe to credential updates.This returns a function which can be used to remove the event listener
     * when the component unmounts.
     */
    this.authCredentialListener = appleAuth.onCredentialRevoked(async () => {
      // console.warn('Credential Revoked');
      this.fetchAndUpdateCredentialState().catch(error =>
        this.setState({credentialStateForUser: `Error: ${error.code}`}),
      );
    });

    this.fetchAndUpdateCredentialState()
      .then(res => this.setState({credentialStateForUser: res}))
      .catch(error =>
        this.setState({credentialStateForUser: `Error: ${error.code}`}),
      );
  }

  componentWillUnmount() {
    /**
     * cleans up event listener
     */
    this.authCredentialListener();
  }

  signIn = async () => {
    // start a login request
    try {
      const appleAuthRequestResponse = await appleAuth.performRequest({
        requestedOperation: AppleAuthRequestOperation.LOGIN,
        requestedScopes: [
          AppleAuthRequestScope.EMAIL,
          AppleAuthRequestScope.FULL_NAME,
        ],
      });
      this.setState({loading: true});
      const {
        user: newUser,
        email,
        nonce,
        fullName: {familyName, givenName},
        identityToken,
        realUserStatus /* etc */,
      } = appleAuthRequestResponse;
      let username = `${givenName} ${familyName}`;

      this.user = newUser;

      this.fetchAndUpdateCredentialState()
        .then(res => {
          this.setState({credentialStateForUser: res});
          console.log('res:::', res);
        })
        .catch(error => {
          console.log(`Error: ${error.code}`);
          this.setState({credentialStateForUser: `Error: ${error.code}`});
        });

      if (identityToken) {
        console.log('email', email);
        console.log('username', username);
        console.log('nonce', nonce);
        this.sendData(email, username, nonce);
        // e.g. sign in with Firebase Auth using `nonce` & `identityToken`
      } else {
        // no token - failed sign-in?
      }

      if (realUserStatus === AppleAuthRealUserStatus.LIKELY_REAL) {
        console.log("I'm a real person!");
      }

      // console.warn(`Apple Authentication Completed, ${this.user}, ${email}`);
    } catch (error) {
      if (error.code === AppleAuthError.CANCELED) {
        alert('User canceled Apple Sign in');
        // console.warn('User canceled Apple Sign in.');
      } else {
        console.error(error);
      }
    }
  };

  fetchAndUpdateCredentialState = async () => {
    if (this.user === null) {
      this.setState({credentialStateForUser: 'N/A'});
    } else {
      const credentialState = await appleAuth.getCredentialStateForUser(
        this.user,
      );
      if (credentialState === AppleAuthCredentialState.AUTHORIZED) {
        this.setState({credentialStateForUser: 'AUTHORIZED'});
      } else {
        this.setState({credentialStateForUser: credentialState});
      }
    }
  };

  // Send data "name,image,email" to API
  sendData = async (Email, Name, Id) => {
    try {
      let response = await API.post('/apple', {
        email: Email,
        name: Name,
        id: Id,
      });
      let {
        data: {
          data: {
            response: {token},
          },
        },
      } = response;
      console.log('token:?>:', token);
      console.log('props', this.props);
      console.log('navigation', this.props.navigation);
      this.setState({loading: false});
      this.props.storeToken(token);
      this.props.isLogin(true);
      // this.props.navigation.push('BottomTabNavigator');
    } catch (err) {
      console.log(err);
      alert('Unexpected Error, try again later.');
      this.setState({loading: false});
    }
  };

  render() {
    return (
      <View style={styles.container}>
        {this.state.loading ? (
          <ActivityIndicator />
        ) : (
          <AppleButton
            style={styles.appleButton}
            cornerRadius={5}
            buttonStyle={AppleButton.Style.WHITE}
            buttonType={AppleButton.Type.SIGN_IN}
            onPress={() => this.signIn()}
          />
        )}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  appleButton: {
    width: 200,
    height: 50,
    // margin: 10,
  },
  container: {
    flex: 1,
    justifyContent: 'center',
  },
});

const mapDispatchToProps = dispatch => {
  // to excute the actions we want to invok
  return {
    isLogin: isLogin => {
      dispatch(isLoginFunc(isLogin));
    },
    storeToken: token => {
      dispatch(saveToken(token));
    },
  };
};

export default connect(
  null,
  mapDispatchToProps,
)(AppleAuth);

- поющие.js

<AppleAuth /> в методе рендеринга


person Oliver D    schedule 19.05.2020    source источник


Ответы (1)


если вы визуализируете свой компонент как компонент, а не как экран навигации, он не получит поддержку навигации. Так было во всех версиях react-navigation Доступ к навигационной опоре из любого компонента

person Max    schedule 19.05.2020