React-навигация импортирована, но не определена

#reactjs #react-native #react-redux #firebase-authentication #react-navigation

#reactjs #react-native #реагировать-redux #firebase-аутентификация #react-навигация

Вопрос:

Мое приложение, основанное на react, использует react-redux и react-navigation.

App.js импортирует Main компонент. Внутри Main импортируется react-navigation и определяются все навигаторы. Тем не менее, я все еще получаю ошибку типа: неопределенный не является объектом (вычисление ‘that.navigation.navigate’)] на that.navigation.navigate('Auth') в Main .

Я также пробовал, navigation.navigate('Auth') но не могу найти переменную: navigation. Является ли плохой практикой импортировать react-navigation и использовать его в одном файле? Я хотел бы использовать навигацию в, Main чтобы избежать вызова firebase.auth().onAuthStateChanged на каждом экране.

App.js

 ...

const store = createStore(reducers, {}, applyMiddleware(ReduxThunk));

class App extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <Main />
      </Provider>
    );
  }
}

export default App;
  

Main.js

 import React from 'react';
import { createStackNavigator, createSwitchNavigator, createAppContainer } from 'react-navigation';

...

const MainStack = createSwitchNavigator(
  {
    Home: HomeStack,
    Auth: AuthStack
  },
  {
    initialRouteName: 'Home'
  }
);

const AppContainer = createAppContainer(MainStack);

class Main extends React.Component {
  constructor(props) {
    super(props);
  }

  componentDidMount = () => {
    var that = this;
    firebase.auth().onAuthStateChanged(async function(user) {
        if (user) {
            await that.props.getUserProfile(user.uid);
        } else {
            that.navigation.navigate('Auth');
        }
    })
  }

  render() {
    return (
      <AppContainer />
    );
  }
}

const mapStateToProps = state => {
  return {
      user: state.auth.user
  }
}

export default connect(mapStateToProps, {getUserProfile})(Main);
  

Ответ №1:

У вас есть реквизиты.

Изменить that.navigation.navigate('Auth'); на that.props.navigation.navigate('Auth');

Комментарии:

1. Не работает; навигация в этом случае не передается из реквизитов

Ответ №2:

Я не уверен, потому что я никогда не использовал react navigation, но похоже, что только AppContainer и его дочерние элементы обернуты, а не основной компонент, поэтому навигация здесь не определена. Вам следует пересмотреть порядок архитектуры вашего компонента


Форма https://facebook.github.io/react-native/docs/navigation

Каждый компонент экрана может устанавливать параметры навигации, такие как заголовок заголовка. Он может использовать создателей действий в navigation реквизите для ссылки на другие экраны

Ваш Main компонент не является экраном, вы не можете использовать навигацию в нем.

Вы можете сделать что-то подобное :

 const AppContainer = isAuthentified => createAppContainer(createStackNavigator(
 {
  Home: HomeStack,
  Auth: AuthStack
 },
 {initialRouteName: !!isAuthentified ? 'Home' : 'Auth'}
)); 


class Main extends React.Component {
  constructor(props) {
   super(props);
   state = {loading: false};
  }

  componentDidMount = () => {
   let tmpuser = false; 
   firebase.auth().onAuthStateChanged(async function(user) {
    if (user) {
        tmpuser = await that.props.getUserProfile(user.uid);
    }});
   this.setState({user: tmpuser, loading: false})
  }

  render() {
   if (!this.state.loading) 
    return (
     <div>{AppContainer(this.state.user)}</div>
    );
   else return (<div>loading</div>);
  }
}
  

// Может быть не идеальным, сделано на смартфоне

Комментарии:

1. Да, я мог бы вызвать firebase.auth().onAuthStateChanged на одном из моих экранов в домашнем стеке, но тогда он вызывается каждый раз, когда я перехожу к новому экрану. Причина Main здесь заключается в том, чтобы вызвать функцию только один раз

2. MainStack — это switch navigator, не уверен, как вы планируете это делать там?

3. Я не думаю, что вы говорите об одном и том же, мне нужно куда-то позвонить firebase.auth().onAuthStateChanged , это невозможно сделать в MainStack, потому что это просто навигатор

4. Можете ли вы указать это в своем ответе, это трудно понять