I am trying to put in a RBAC login system into my expo app and i am having trouble getting my app file functioning correctly with redux.
I am trying to put together a role based access system for what was originally an expo app but i have tried adding a RBAC to the app.js file from a create react app tutorial. I have the basic components created for general users so but i am encountering a error which i think is to do with redux.
The error i get when i run expo start is as follows:
** Error: 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. **
app.js
import React, { useEffect, useState, Component } from 'react';
import 'react-native-gesture-handler';
import { NavigationContainer} from "@react-navigation/native";
import { createStackNavigator} from "@react-navigation/stack";
import { navigationRef } from "./RootNavigation";
import { useDespatch, useSelector, Connect, Provider } from "react-redux";
import { Router, Switch, Route, Link } from "react-router-dom";
import { AppLoading } from "expo";
import { StatusBar } from 'expo-status-bar';
import { decode, encode } from 'base-64';
//import "./index";
import { LoginScreen, home, RegistrationScreen } from './screens';
import newsDetail from "./components/newsDetail";
import AboutSustScub from "./components/about";
import SearchScubaSchool from "./components/user/searchSchool";
import MarineLife from "./components/general/marineLife";
import Profile from "./components/general/profile";
import Messenger from "./components/general/messenger";
import HeaderMenu from "./components/header";
import Footer from './components/footer';
import "bootstrap/dist/css/bootstrap.min.css";
import "./App.css";
import { logOut } from "./actions/auth";
import { clear_Message } from "./actions/message";
import store from "./store";
import { history } from "./helpers/history";
const Stack = createStackNavigator();
class App extends Component {
constructor(props) {
super(props);
this.logOut = this.logOut.bind(this);
this.state = {
showUserLevelAccess: false,
showSchoolLevelAccess: false,
showAdminLevelAccess: false,
showSuperUserAccess: false,
currentUser: undefined,
};
history.listen((location) => {
props.dispatch(clearMessage());
});
}
componentDidMount() {
const user = this.props.user;
if (user) {
this.setState({
currentUser: user,
showUserLevelAccess: user.userRoles.includes(1),
showSchoolLevelAccess: user.userRoles.includes(2),
showSiteAdminLevelAccess: user.userRoles.includes(3),
showSuperUserLevelAccess: user.userRoles.includes(4),
});
}
}
logOut() {
this.props.dispatch(logout());
}
render() {
const {
currentUser,
showUserLevelAccess,
showSchoolLevelAccess,
showSiteAdminLevelAccess,
showSuperUserLevelAccess
} = this.state;
return (
<Provider store={store}>
<NavigationContainer>
<Stack.Navigator>
state.userToken == null ? (
<>
// if no user token is found user will be displayed login or regisration screens
<Stack.Screen name="Login" component={LoginScreen}/>
<Stack.Screen name="Registration" component={RegistrationScreen}/>
</>
) : (
<>
// If user token found they will be displayed the below components
{ currentUser && (
<Stack.Screen
name="Homepage"
component={HomePage}
options={{
header: () => <HeaderMenu headerDisplay="Home page"/>
}}
/>
)}
{ currentUser && (
<Stack.Screen
name="newsDetail"
component={newsDetail}
options={{
header: () => <HeaderMenu headerDisplay="Scuba News"/>
}}
/>
)}
{ currentUser && (
<Stack.Screen
name="about"
component={AboutSustScub}
options={{
header: () => <HeaderMenu headerDisplay="About Sustainable Scuba"/>
}}
/>
)}
{ currentUser && (
<Stack.Screen
name="SearchScubaSchool"
component={SearchScubaSchool}
options={{
header: () => <HeaderMenu headerDisplay="Search for your perfect scuba school"/>
}}
/>
)}
{ currentUser && (
<Stack.Screen
name="MarineLife"
component={MarineLife}
options={{
header: () => <HeaderMenu headerDisplay="Marine life educational information"/>
}}
/>
)}
{ currentUser && (
<Stack.Screen
name="Profile"
component={Profile}
options={{
header: () => <HeaderMenu headerDisplay="Profile with PADI information"/>
}}
/>
)}
{ currentUser && (
<Stack.Screen
name="Messenger"
component={Messenger}
options={{
header: () => <HeaderMenu headerDisplay="Personal messages and notifications"/>
}}
/>
)}
</>
)
</Stack.Navigator>
</NavigationContainer>
</Provider>
);
}
}
function mapStateToProps(state){
const { user } = state.auth;
return {
user,
};
}
export default Connect(mapStateToProps)(App);
index.js
import { registerRootComponent} from "expo";
import React from "react";
import ReactDOM from "react-dom";
import { useDespatch, useSelector, connect, Provider } from "react-redux";
import store from "./store";
import "./index.css";
import App from "./App";
import {BrowserRouter} from "react-router-dom";
// registerRootComponent calls AppRegistry.registerComponent('main', () => App);
// It also ensures that whether you load the app in the Expo client or in a native build,
// the environment is et up appropriately
ReactDOM.render(
// Provider passes the store to the component nested within it
<Provider store={store}>
<BrowserRouter>
registerRootComponent(App);
</BrowserRouter>
</Provider>,
document.getElementById("root")
);
store.js
import { createStore, applyMiddleware} from "redux";
import { composeWithDevTools } from "redux-devtools-extension";
import thunk from "redux-thunk";
import rootReducer from "./reducers";
const middleware = [thunk];
const store = createStore(
rootReducer,
composeWithDevTools(applyMiddleware(...middleware))
);
export default store;
// redux store brings actions and reducers together and holds application state
I think i need to move the connect to the rootcontainer component and pass connect the rootcontainer and not the app component but i’m not sure i’m doing it correctly.
I have tried to add a create react app tutorial to my expo app so the problem could be something to do with that. Any feedback would be much appreciated.