React native — аутентификация firebase с реакцией-редукцией в App.js

Я использую аутентификацию Firebase и реагирую на редукцию в своем приложении. Я добавил firebase.auth().onAuthStateChanged в функцию componentDidMount моего App.js, чтобы проверять статус входа пользователя в приложение. Я попытался подключить App.js к моей функции редукции действий getUserProfile следующим образом:

App.js

import React from 'react';
import { createStackNavigator, createAppContainer } from 'react-navigation';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux'; 
import reducers from './app/src/reducers';
import ReduxThunk from 'redux-thunk';
import { connect } from 'react-redux';
import { firebase } from './config/config';
import { getUserProfile } from './app/src/actions/index';

...

const AppContainer = createAppContainer(MainStack);

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

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

  render() {
    const store = createStore(reducers, {}, applyMiddleware(ReduxThunk));
    return (
      <Provider store = {store}>
        <AppContainer/>
      </Provider>
    );
  }
}

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

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

Я получил ошибку: Нарушение инварианта: не удалось найти «магазин» в контексте «Подключить (приложение)». Либо оберните корневой компонент в , либо передайте пользовательский поставщик контекста React и соответствующий потребитель контекста React в Connect(App) в параметрах подключения. Как это исправить?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
0
986
1

Ответы 1

Я вижу проблему сейчас. Вы используете соединять для компонента, который является родительским для компонента Провайдер.

Что вам нужно сделать, так это создать новый компонент с именем Основной и использовать для него соединять. Ваш компонент Приложение не может использовать соединение, поскольку он не является дочерним элементом Провайдер, а является родителем.

Или другими словами:

App.js

import React from 'react';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux'; 
import reducers from './app/src/reducers';
import ReduxThunk from 'redux-thunk';

...

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, createAppContainer } from 'react-navigation';
import { connect } from 'react-redux';
import { firebase } from './config/config';
import { getUserProfile } from './app/src/actions/index';

...

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.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);

Спасибо, это имеет смысл, другим компонентам не нужно вызывать сам Main, верно? Потому что он содержится в App.js

JAM 25.03.2019 22:57

Единственная проблема в том, что теперь я получаю undefined is not an object (evaluating 'that.navigation.navigate') внутри componentDidMount в main.js

JAM 25.03.2019 22:59

Странный. Может быть, попробуйте передать navigation = {this.navigation} в Main.

Joshua Obritsch 25.03.2019 23:11

Я не понимаю, MainStack — это просто навигатор свитчей с разными стеками внутри него

JAM 25.03.2019 23:12

Обычно передача navigation = {this.navigation} компоненту исправила бы это, но в этом случае main.js напрямую импортирует реагирующую навигацию...

JAM 25.03.2019 23:13

Вот как я обычно перемещаюсь: reactnavigation.org/docs/en/…

Joshua Obritsch 25.03.2019 23:34

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

JAM 25.03.2019 23:44

Другие вопросы по теме