1

I am using Firebase authentication and react-redux in my app. I added firebase.auth().onAuthStateChanged to my App.js's componentDidMount function to check for user login status throughout the app. I tried connecting App.js to my redux actions's function getUserProfile like this:

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

I got the error: Invariant Violation: Could not find "store" in the context of "Connect(App)". Either wrap the root component in a , or pass a custom React context provider to and the corresponding React context consumer to Connect(App) in connect options. How do I fix this?

1 Answer 1

1

I see the problem now. You are using connect on a component that is the parent of the Provider component.

What you need to do is create a new component called Main and use connect on that. Your App component cannot use connect because it is not a child of Provider, instead it is the parent.

Or in other words:

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);
Sign up to request clarification or add additional context in comments.

7 Comments

Thank you this makes sense, other components do not need to call Main itself right? Because it is contained by App.js
Only issue is now I am getting undefined is not an object (evaluating 'that.navigation.navigate') inside componentDidMount in main.js
Strange. Maybe try passing navigation={this.navigation} down to Main.
I don't follow, MainStack is just a switch navigator with different stacks inside of it
Usually, passing navigation={this.navigation} down to the component would fix it but in this case, main.js imports react-navigation directly...
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.