I'm trying to implement react-redux in my react-native application.
In my root index, I wrote :
import {createStore} from 'redux';
import rootReducer from './src/reducers';
import {Provider} from 'react-redux';
const store = createStore(rootReducer);
AppRegistry.registerComponent(appName, () => (
<Provider store={store}>
<App />
</Provider>
));
And the App looks like this :
const App: () => React$Node = () => {
return (
<>
<NavigationContainer>
<Stack.Navigator>
......
</Stack.Navigator>
</NavigationContainer>
</>
);
};
export default App;
But Metro server keeps giving me : [Wed Aug 12 2020 11:06:14.345] ERROR ReferenceError: Can't find variable: React
You have to import React in root index as well
import React from 'react';
This is not required in normal scenarios but as you are using jsx tags in root index this is required.
Or you can do the provider setup in App.js
You need this line in the root index file
import React from 'react';
Just added the reducers in App.js. And everything is now working fine.
Related
I can't seem to figure out what seems to be the issue. I am getting a render error, "Could'nt find a 'component'; get component or children prop for the screen dashboard. This can happen if you passed 'undefined'. You likely forgot to export your component from the file it's defined.
My code in App.js is as follows:
```
import React from "react";
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import {
MainLayout
} from "./screens";
const Stack = createNativeStackNavigator();
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator
screenOptions={{
headerShown: false
}}
initialRouteName={'Dashboard'}
>
<Stack.Screen
name="Dashboard"
component={MainLayout}
/>
</Stack.Navigator>
</NavigationContainer>
)
}
export default App
```
My code in /screens/Dashboard/MainLayout is as follows:
```
import React from 'react';
import {
View,
Text
} from 'react-native';
const MainLayout = () => {
return (
<View>
<Text>MainLayout</Text>
</View>
)
}
export default MainLayout;
```
You are exporting MainLayout as default so import it without { }. You can import default component with any name but non default components with exact name inside { }.
Change your import in App.js like below ( It seems that you also not given full path)
... // rest of imports
import MainLayout from "./screens/Dashboard/MainLayout";
... // rest of codes
Click here to know more about Importing and Exporting
I want to redirect my current app screen to login screen if the user is not authenticated. So I created a global component RedirectorToLogin and use this component in my App.js . But I'm getting this error Couldn't find a navigation object. Is your component inside a screen in a navigator ? because I'm using useNavigation inside RedirectorToLogin.
What is the reason for this error to be occured ?
My RedirectorToLogin.js
import React, { useContext, useEffect } from 'react'
import { useNavigation } from '#react-navigation/native'
import AuthGlobal from '../Context/store/AuthGlobal'
const RedirectorToLogin = (props) => {
const context = useContext(AuthGlobal)
const navigation = useNavigation()
useEffect(() => {
if (!context.stateUser.isAuthenticated) {
navigation.navigate('Login')
}
return () => {}
}, [context.stateUser.isAuthenticated])
return <></>
}
export default RedirectorToLogin
My App.js
import { StatusBar } from 'expo-status-bar'
import React from 'react'
import { LogBox } from 'react-native'
import { NavigationContainer } from '#react-navigation/native'
import Toast from 'react-native-toast-message'
import ErrorBoundary from 'react-native-error-boundary'
// Redux
import { Provider } from 'react-redux'
import store from './Redux/store'
// Context API
import Auth from './Context/store/Auth'
// Navigatiors
import Main from './Navigators/Main'
// Screens
import Header from './Shared/Header'
import MyAppState from './Global/MyAppState'
import Network from './Global/Network'
import RedirectorToLogin from './Global/RedirectorToLogin'
const errorHandler = (error, stackTrace) => {
/* Log the error to an error reporting service */
console.log('**** error log form error handler ****')
console.log(error)
console.log(stackTrace)
console.log('**** **** ****')
}
LogBox.ignoreAllLogs(true)
export default function App() {
return (
<ErrorBoundary onError={errorHandler}>
<Auth>
<Provider store={store}>
<NavigationContainer>
<Header />
<Main />
<MyAppState />
<Network />
<RedirectorToLogin />
<Toast ref={(ref) => Toast.setRef(ref)} />
</NavigationContainer>
</Provider>
</Auth>
</ErrorBoundary>
)
}
I referred to this article and updated my Main.js to show only login navigator when user is not authenticated. So I can get rid of having RedirectorToLogin
I am new to coding and react native. I have been trying to set up an app with just some basic pages to practice with react navigation but keep getting thrown an error.
Failed building JavaScript bundle.
Unable to resolve "./src/navigation/MainTabs" from "src/navigation/AppNavigator.js"
I am using expo and have installed these npm:
npm install #react-navigation/native
expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context #react-native-community/masked-view
npm install #react-navigation/stack
Here is my code so far:
App.js
import * as React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import AppNavigator from './src/navigation/AppNavigator.js';
const App = () => {
return (
<NavigationContainer>
<AppNavigator />
</NavigationContainer>
);
}
export default App;
AppNavigator.js
import * as React from 'react';
import { createStackNavigator } from '#react-navigation/stack';
import MainTabs from './src/navigation/MainTabs';
const Stack = createStackNavigator();
const AppNavigator = () => {
return (
<Stack.Navigator>
<Stack.Screen name='MainTabs' component={MainTabs} />
</Stack.Navigator>
);
}
export default AppNavigator;
MainTabs.js
import * as React from 'react';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import PartyMenuScreen from './src/screens/PartyMenuScreen';
import TableMenuScreen from './src/screens/TableMenuScreen';
import VacationMenuScreen from './src/screens/VacationMenuScreen';
const Tabs = createBottomTabNavigator();
const MainTabs = () => {
return (
<Tab.Navigator>
<Tab.Screen name='Party Games' component={PartyMenuScreen} />
<Tab.Screen name='Table Games' component={TableMenuScreen} />
<Tab.Screen name='Vacation Games' component={VacationMenuScreen} />
</Tab.Navigator>
);
}
export default MainTabs;
I have tried reinstalling the npm modules and renaming file paths. Beyond that I am not sure what to do. I believe it may have something to do with my dependencies but I am not sure how to troubleshoot them.
You have error in AppNavigator.js import path for
import MainTabs from './src/navigation/MainTabs';
From the error message, I am assuming you have AppNavigator.js and MainTabs.js at the same level in folder hierarchy.
Replace above import with below:
import MainTabs from './MainTabs';
Resolved the issue. Used ../ for the imports because of the folder they were located in and changed the Tabs to Tab.
I have the following code in App.js file:-
import React, { Component } from 'react';
import { Platform, StyleSheet, Text, View } from 'react-native';
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import { NavigationContainer} from "react-navigation";
const Home = ({ navigation }) => {
return (
<View>
<Text>This is Home page!</Text>
</View>
)
}
const Stack = createStackNavigator();
function MyStack() {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
</Stack.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<MyStack />
</NavigationContainer>
);
}
I followed the same instruction on this page:- https://reactnavigation.org/docs/stack-navigator/
But it gave an error
I fixed the issue by following the version 4 documentation
The problem is that when i installed the react-navigation package by following these commands:-
yarn add #react-navigation/native
I assumed by default if i install any package without defining a specific version, it suppose to install the latest current version of that package which is (v5) any by default i followed the package documentation for the version 5 . and when i checked the installed package version i noticed that the version 4 is installed no 5 .
Now i used the version 4 stack creating syntax :-
const navigator = createStackNavigator({
Home:Home,
},
{
initialRouteName: 'Home'
});
export default createAppContainer(navigator);
Every thing work fine now
Here is the URL for the
V5 https://reactnavigation.org/docs/hello-react-navigation
V4 https://reactnavigation.org/docs/4.x/getting-started
Try to import createStacknavigator as below:
import {createStacknavigator} from '#react-navigation/stack';
This worked for me in no time.
Import your navigator files from;
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
I am using redux-persist with redux toolkit.
here is my store configuration.
I haven't implemented or configured store before.
I intend to persist user state after login.
Currently after login, if I reload app in emulator it always goes back to login screen.
is my store configured properly?
updated store file:
import {configureStore} from '#reduxjs/toolkit';
import authReducer from '../features/login/authSlice';
import AsyncStorage from '#react-native-community/async-storage';
import {persistReducer, persistStore} from 'redux-persist';
import {combineReducers} from 'redux';
import hardSet from 'redux-persist/lib/stateReconciler/hardSet';
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
const reducers = combineReducers({
auth: authReducer,
// other reducers goes here...
});
const persistConfig = {
key: 'root',
storage: AsyncStorage,
// stateReconciler: hardSet,
};
const _persistedReducer = persistReducer(persistConfig, reducers);
export const store = configureStore({
reducer: _persistedReducer,
});
export const persistor = persistStore(store);
My index.js file where i wrap my root component with PersistGate
import React from 'react';
import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
import {store, persistor} from './src/stores/store';
import {Provider} from 'react-redux';
import {storeUser, storeRefreshToken} from './src/features/login/authSlice';
import {PersistGate} from 'redux-persist/lib/integration/react';
const RNRedux = () => (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>
);
AppRegistry.registerComponent(appName, () => RNRedux);
Error I get currently:
I think you need to use persistStore. You should store your app store in persistStore and then use persistGate.
PersistGate delays the rendering of your app's UI until your persisted state has been retrieved and saved to redux.
So, your store file can be :
import { persistStore } from 'redux-persist';
const persistor = persistStore(store);
export { persistor, store };
And your app.js will be :
import { store, persistor } from 'path_to_your_store/store';
<Provider store={store}>
<PersistGate persistor={persistor}>
</App>
</PersistGate>
</Provider>
This appears to be an issue with redux-persist passing a function as an action type which is not recommended by the Redux devs. Redux Toolkit was developed with defaults to help avoid the creation of breakable code. It's RTK's default middleware "serializableCheck" that throws this error. This middleware can be disabled outright or just for specific actions, and both methods are provided by example in answers to this SO question. RTK middleware documentation here for quick reference.
Here's a blanket solution that should work for you:
- import {configureStore} from '#reduxjs/toolkit';
+ import {configureStore, getDefaultMiddleware} from '#reduxjs/toolkit';
...
export const store = configureStore({
reducer: _persistedReducer,
+ middleware: getDefaultMiddleware({
+ serializableCheck: false
+ }),
});
...