Reputation: 1409
I am trying to setup react navigation v3 with redux. In the react navigation docs I can successfully set up my navigation and it works fine without redux added. However, when I attempt to add my redux class App extends React.Component{...}
and hook up my actions it throws the following error:
Invariant Violation: Invariant Violation: Could not find "store" in the context of "Connect(AuthScreen)". Either wrap the root component in a , or pass a custom React context provider to and the corresponding React context consumer to Connect(AuthScreen) in connect options.
App.js
const MainNavigator = createBottomTabNavigator({
welcome: { screen: WelcomeScreen },
auth: { screen: AuthScreen },
main: {
screen: createBottomTabNavigator({
map: { screen: MapScreen },
deck: { screen: DeckScreen },
review: {
screen: createStackNavigator({
review: { screen: ReviewScreen },
settings: { screen: SettingsScreen }
})
}
})
}
});
const AppContainer = createAppContainer(MainNavigator);
class App extends React.Component {
render() {
return (
<Provider store={store}>
<AppContainer />
</Provider>
);
}
}
export default AppContainer;
Here is my AuthScreen I want to connect redux to:
class AuthScreen extends Component {
componentDidMount(){
console.log('This is this.props in AuthScreen:')
console.log(this.props);
this.props.facebookLogin();
}
render(){
return(
<View>
<Text>AuthScreen</Text>
</View>
)
}
}
export default connect(null, actions)(AuthScreen);
I suspect I am not allowed to wrap the <Provider>
tags around the app container like this, can someone give some insight on how this could be done?
Upvotes: 3
Views: 7070
Reputation: 17297
Here's a simple example to get you started with React Navigation 3.x and Redux:
App.js
import React, {Component} from 'react';
import {createStackNavigator, createAppContainer} from 'react-navigation';
import {Provider} from 'react-redux';
import {createStore, applyMiddleware} from 'redux';
import Reducers from './src/Reducers';
import Preload from './src/screens/Preload';
let store = createStore(Reducers);
const AppNavigator = createStackNavigator({
Preload: {
screen: Preload,
},
});
const AppContainer = createAppContainer(AppNavigator);
export default class App extends Component {
render () {
return (
<Provider store={store}>
<AppContainer/>
</Provider>
)
}
}
Upvotes: 11
Reputation: 1158
So, I'll post what I have and hopefully it will help. I have a separated file (AppNavigation.js) that handles all the navigation for my app. On this AppNavigation I have this:
const RootNavigator = createStackNavigator({
<Code here>
})
My RootNavigator is inside the AppContainer
const AppContainer = createAppContainer(RootNavigator)
Then, on my class I render the AppContainer.
class AppNavigation extends Component {
constructor(props) {
super(props);
}
render() {
return <AppContainer screenProps={this.props} />
}
}
export default connect(mapStateToProps, mapDispatchToProps)(AppNavigation);
Then, on my App.js I 'connect' my store to the RootNavigator
export default class App extends React.Component {
render() {
return (
<Provider store={store}>
<RootNavigator />
</Provider>
)
}
}
So, long story short: you should wrap your MainNavigator on your Provider tag.
EDIT:
const rootReducer = combineReducers({
reducer1,
reducer2,
reducer3...,
})
export default createStore(
rootReducer,
undefined,
applyMiddleware(...middleware)
)
So with these reducers you can 'connect' them to your component via mapStateToProps and use the state of the reducers on them.
Upvotes: 5