I have started learning react-native and I'm experiencing some issues. I don't seem to be able to use both components (createBottomTabNavigator and createStackNavigator). Export default can only be used once and I would like to render both components(at the moment only one or the other is rendering).
It would be great to get some help. thanks
Navigation.js
import { createAppContainer } from 'react-navigation'
import { createStackNavigator } from 'react-navigation-stack'
import { createBottomTabNavigator } from 'react-navigation-tabs'
import Search from '../Components/Search'
import Favourites from '../Components/Favourites'
import FilmDetail from '../Components/FilmDetail'
const SearchStackNavigator = createStackNavigator({
Search: {
screen: Search,
navigationOptions: {
title: 'Search Film'
}
},
FilmDetail: {
screen: FilmDetail,
navigationOptions: {
title: 'Film Details'
}
}
})
const MoviesTabNavigator = createBottomTabNavigator({
Search: {
screen: Search
},
Favourites: {
screen: Favourites
}
})
export default createAppContainer(MoviesTabNavigator)
I'm aware that I'm not using the latest version of React-Native
Package.json
{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"eject": "expo eject"
},
"dependencies": {
"#react-native-community/masked-view": "^0.1.10",
"expo": "~39.0.2",
"expo-cli": "^3.28.5",
"expo-status-bar": "~1.0.2",
"moment": "^2.29.1",
"numeral": "^2.0.6",
"react": "16.13.1",
"react-dom": "^16.9.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-39.0.3.tar.gz",
"react-native-gesture-handler": "^1.6.1",
"react-native-reanimated": "^1.8.0",
"react-native-safe-area-context": "^1.0.0",
"react-native-screens": "^2.7.0",
"react-native-web": "^0.11.7",
"react-navigation": "^4.3.9",
"react-navigation-stack": "^2.5.0",
"react-navigation-tabs": "^2.8.13",
"react-redux": "^7.2.2",
"redux": "^4.0.5"
},
"devDependencies": {
"#babel/core": "~7.9.0"
},
"private": true
}
here is my App.js
import React from 'react'
import Navigation from './Navigation/Navigation'
import { Provider } from 'react-redux'
import Store from './Store/configureStore'
export default class App extends React.Component {
render() {
return (
<Provider store={Store}>
<Navigation/>
</Provider>
);
}
}
Nesting your screen will solve your problem. I assume you want SearchStackNavigator within MoviesTabNavigator. Do something like below
const MoviesTabNavigator = createBottomTabNavigator({
Search: {
screen: SearchStackNavigator
},
Favourites: {
screen: Favourites
}
})
export default createAppContainer(MoviesTabNavigator)
To navigate between stacks and land in a specific screen use:
navigation.navigate('Stack', {screen: 'screenName')
Error seems to be that Search is not referring to your SearchStackNavigator but your "Search" component you import at the top.
Nested Stacks are possible. I'd recommend taking a look here: Master React Navigation 5
I recommend you to use react-navigation 5.x and follow this example:
SearchStackNavigator:
import {createStackNavigator} from '#react-navigation/stack';
const Stack = createStackNavigator();
const SearchStackNavigator = () =>
<Stack.Navigator>
<Stack.Screen
name="Search"
component={Search}
/>
<Stack.Screen
name="FilmDetail"
component={FilmDetail}
/>
</Stack.Navigator>
MoviesTabNavigator:
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import SearchStackNavigator from "./SearchStackNavigator";
const Tab = createBottomTabNavigator();
const MoviesTabNavigator = () =>
<Tab.Navigator>
<Tab.Screen
name="Search"
component={SearchStackNavigator} />
<Tab.Screen
name="Other tab"
component={OTHER STACK OR SCREEN HERE} />
</Tab.Navigator>
react-navigation docs:
bottom-tab docs
stack-navigation docs
Related
Tailwind CSS in the native wind is not being applied on Screen components.
Is there any package or dependency that is missing in my project .
This is a package.json
{
"name": "first-app",
"version": "1.0.0",
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"
},
"dependencies": {
"#react-navigation/native": "^6.0.13",
"#react-navigation/native-stack": "^6.9.1",
"expo": "~46.0.13",
"expo-status-bar": "~1.4.0",
"nativewind": "^2.0.11",
"react": "18.0.0",
"react-native": "0.69.6",
"react-native-safe-area-context": "4.3.1",
"react-native-screens": "~3.15.0"
},
"devDependencies": {
"#babel/core": "^7.12.9",
"tailwindcss": "^3.2.0"
},
"private": true
}
Tailwind CSS is Applied on App.js but on screens components
import { StatusBar } from 'expo-status-bar';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import HomeScreen from './screens/HomeScreen';
export default function App() {
const Stack = createNativeStackNavigator();
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
This is Screen Component where native wind ( tailwind ) is not Applied
import { View, Text } from 'react-native'
import React from 'react'
const HomeScreen = () => {
return (
<View className="flex-1 text-center align-middle justify-center">
<Text className="bg-black text-white">App</Text>
</View>
)
}
export default HomeScreen
Firstly my tailwind.config.js Looks like this
module.exports = {
content: ["./App.{js,jsx,ts,tsx}", "./components/**/*.{js,jsx,ts,tsx}", "./screens/**/*.{js,jsx,ts,tsx}"],
theme: {
extend: {},
},
plugins: [],
}
Then I CHANGED IT WITH FOLLOWING CODE. THE MAIN CHANGE WAS IN content part. By applying the above change tailwindcss started applying both in screens and components. This worked for me
module.exports = {
content:[
"./screens/**/*.{js,jsx,ts,tsx}",
"./pages/**/*.{js,jsx,ts,tsx}",
"./components/**/*.{js,jsx,ts,tsx}",
],
theme: {
extend: {},
},
plugins: [],
};
Hoping someone can help as i'm struggling to see what the issue is.
When using react-native-navigation to create a stack navigator, no matter what approach I use to export and import the component to pass into the <Stack.Screen/>, it seems to throw the below error.
React Native Issue
Stack Trace
Error: Couldn't find a 'component', 'getComponent' or 'children' prop for the screen 'Home'. This can happen if you passed 'undefined'. You likely forgot to export your component from the file it's defined in, or mixed up default import and named import when importing.
After seeing this stack trace, i done a console.log() and passed in the component just to see if undefined was being returned. This wasn't the case. I can see the HomeComp component for example be
package.json
"name": "myApp",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint ."
},
"dependencies": {
"#react-native-community/masked-view": "^0.1.10",
"#react-navigation/native": "^5.8.0",
"#react-navigation/stack": "^5.10.0",
"axios": "^0.21.0",
"body-parser": "^1.19.0",
"connect-flash": "^0.1.1",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"express-validator": "^6.6.1",
"mongoose": "^5.10.10",
"react": "16.13.1",
"react-native": "0.63.3",
"react-native-gesture-handler": "^1.8.0",
"react-native-reanimated": "^1.13.1",
"react-native-safe-area-context": "^3.1.8",
"react-native-screens": "^2.12.0"
},
"devDependencies": {
"#babel/core": "7.12.3",
"#babel/runtime": "7.12.1",
"#react-native-community/eslint-config": "1.1.0",
"babel-jest": "25.5.1",
"eslint": "6.8.0",
"jest": "25.5.4",
"metro-react-native-babel-preset": "0.59.0",
"react-test-renderer": "16.13.1"
},
"jest": {
"preset": "react-native"
}
}
HomeComp.js
import React, { useState, useEffect } from 'react';
import { View, StyleSheet, Text, FlatList } from 'react-native';
function HomeComp() {
return (
<View>
<Text>Welcome!</Text>
</View>
)
}
const styles = StyleSheet.create({
container: {
//paddingTop: 30,
},
text: {
fontSize: 20,
margin: 10
},
})
export default HomeComp;
app.js
import React, { Component } from 'react';
import { Platform, StyleSheet, Text, View } from 'react-native';
import HomeComp from './src/components/HomeComp';
// import StatefulComponent from './src/components/api_comp';
import { createStackNavigator } from '#react-navigation/stack';
import { NavigationContainer } from '#react-navigation/native';
// To see all the requests in the chrome Dev tools in the network tab.
XMLHttpRequest = GLOBAL.originalXMLHttpRequest ?
GLOBAL.originalXMLHttpRequest :
GLOBAL.XMLHttpRequest;
// fetch logger
global._fetch = fetch;
global.fetch = function (uri, options, ...args) {
return global._fetch(uri, options, ...args).then((response) => {
console.log('Fetch', { request: { uri, options, ...args }, response });
return response;
});
};
function test(){
return(
<View>
<Text>home page</Text>
</View>
);
}
console.log({HomeComp})
export default class App extends Component {
render() {
Stack = createStackNavigator();
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
Component={HomeComp}
/>
<Stack.Screen
name="test"
Component={test}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#1c8282'
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5
}
}); ```
The problem is you are using 'Component' instead of 'component'
you will have to change the prop name to simple case
<Stack.Screen
name="Home"
component={HomeComp}
/>
<Stack.Screen
name="test"
component={test}
/>
As the component prop is not being passed its undefined in the navigator, thats why you are getting the error
I am trying to get a simple example of tab navigation to work in react native. It seems like examples online all assume that a tab navigation screen is the one and only screen in your app, which is not the case for me. In my app I will have a login page, and upon successful login there will be a tab navigation screen I call DashboardTabScreen. The app will have other (non tab) screens available (like Settings or Contact us, or whatever) and each of the tab screens will be the root of a stack of other "detail" screens.
So here is my App.js:
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import LoginScreen from "./src/screens/LoginScreen";
import DashboardTabScreen from "./src/screens/DashboardTabScreen";
const navigator = createStackNavigator(
{
Login: LoginScreen,
DashboardTab: DashboardTabScreen
},
{
initialRouteName: "Login",
defaultNavigationOptions: {
title: "App"
}
}
);
export default createAppContainer(navigator);
And here is my DashboardTabScreen.js
import React, {Component} from "react";
import { Text, StyleSheet, View } from "react-native";
import { createBottomTabNavigator } from 'react-navigation-tabs';
const FirstScreen = () => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>First!</Text>
</View>
);
}
const SecondScreen = () => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Second!</Text>
</View>
);
}
const DashboardTabScreen = createBottomTabNavigator(
{
First: {
screen: FirstScreen,
},
Second: {
screen: SecondScreen,
}
}
);
export default DashboardTabScreen;
When I run the app, it goes to the Login screen as expected. Upon successful login, it should go to this dashboard tab screen. Instead it throws an error:
Invariant violation: Element type is invalid: expected a string (for built-in components) or
a class/function (for composite components) but got undefined. You likely forgot to export
your component from the file it is defined in, or you might have mixed up default and named
imports.
And here is my package.json:
{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"eject": "expo eject"
},
"dependencies": {
"#react-native-community/masked-view": "^0.1.10",
"#react-navigation/bottom-tabs": "^5.4.1",
"#react-navigation/core": "react-navigation/core",
"#react-navigation/native": "^5.2.6",
"#react-navigation/stack": "5.2.3",
"expo": "~36.0.0",
"n": "^6.5.1",
"react": "~16.9.0",
"react-dom": "~16.9.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-36.0.0.tar.gz",
"react-native-gesture-handler": "^1.6.1",
"react-native-reanimated": "^1.8.0",
"react-native-safe-area-context": "^0.6.4",
"react-native-screens": "^2.7.0",
"react-navigation": "^4.3.9",
"react-navigation-stack": "^2.0.16",
"react-navigation-tabs": "^1.2.0",
"stable": "^0.1.8"
},
"devDependencies": {
"#babel/core": "^7.0.0",
"babel-preset-expo": "~8.0.0"
},
"private": true
}
So what is wrong with my code?
I had tried your code it's working perfectly, there is no error in your code:
I think the problem is with react-navigation-tabs version:
change :
"react-navigation-tabs": "^1.2.0",
to
"react-navigation-tabs": "^2.8.7"
Hope this helps!
The problem is with the react-navigation-tabs try to upgrade and then check it.
I'm running the example below locally but get a TypeError.
import HomeScreen from './screens/HomeScreen';
import SecoundScreen from './screens/SecoundScreen';
import ThirdScreen from './screens/ThirdScreen';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
const Stack = createStackNavigator();
function MyStack() {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Second" component={SecoundScreen} />
<Stack.Screen name="Third" component={ThirdScreen} />
</Stack.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<MyStack />
</NavigationContainer>
);
}
I copied the from the example, and it didn't work before I modified it either # https://reactnavigation.org/docs/en/stack-navigator.html
https://snack.expo.io/?platform=android&name=createStackNavigator%20%C2%B7%20React%20Navigation&dependencies=%40react-native-community%2Fmasked-view%40%5E0.1.1%2C%40react-navigation%2Fnative%40%5E5.0.0%2C%40react-navigation%2Fbottom-tabs%40%5E5.0.0%2C%40react-navigation%2Fdrawer%40%5E5.0.0%2C%40react-navigation%2Fmaterial-bottom-tabs%40%5E5.0.0%2C%40react-navigation%2Fmaterial-top-tabs%40%5E5.0.0%2C%40react-navigation%2Fnative-stack%40%5E5.0.0%2C%40react-navigation%2Fstack%40%5E5.0.0%2Creact-native-gesture-handler%401.5.2%2Creact-native-reanimated%401.4.0%2Creact-native-safe-area-context%400.6.0%2Creact-native-screens%402.0.0-alpha.12&sourceUrl=https%3A%2F%2Freactnavigation.org%2Fexamples%2F5.x%2Fsimple-stack.js
The code below is working! I just installed react-navigation, so I should have the latest version!
import React, { useState } from 'react';
import { Button, View } from 'react-native';
import HomeScreen from './screens/HomeScreen';
import SecondScreen from './screens/SecondScreen';
import ThirdScreen from './screens/ThirdScreen';
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
const AppNavigator = createStackNavigator(
{
Home: HomeScreen,
Second: SecondScreen,
Third: ThirdScreen
},
{
initialRouteName: 'Home',
}
);
export default createAppContainer(AppNavigator);
Any idea why the first version is failing?
package.json before and after npm update:
{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"eject": "expo eject"
},
"dependencies": {
"#react-native-community/masked-view": "0.1.5",
"#react-navigation/stack": "^5.0.0",
"expo": "~36.0.0",
"react": "~16.9.0",
"react-dom": "~16.9.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-36.0.0.tar.gz",
"react-native-gesture-handler": "~1.5.0",
"react-native-paper": "^3.6.0",
"react-native-reanimated": "~1.4.0",
"react-native-safe-area-context": "0.6.0",
"react-native-screens": "2.0.0-alpha.12",
"react-native-web": "~0.11.7",
"react-navigation": "^4.1.1",
"react-navigation-fluid-transitions": "^0.3.2",
"react-navigation-stack": "^2.1.1"
},
"devDependencies": {
"babel-preset-expo": "~8.0.0",
"#babel/core": "^7.0.0"
},
"private": true
}
I needed to update the dependencies, this did the trick:
$ npm install -g npm-check-updates
$ npm-check-updates -u
$ npm install
Why I'm still receiving the following:
"The navigation prop is missing for this navigator. In react-navigation 3 you must set up your app container directly."
Here is my code:
const DrawerNavigator = createDrawerNavigator(
{
Home: {
screen: HomeScreen,
},
About: {
screen: Header2,
},
},
DrawerConfig
);
const MyApp11 = createAppContainer(DrawerNavigator);
export default class App12 extends React.Component {
render() {
return <MyApp11 />;
}
}
Working with react native and react navigation.
{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"eject": "expo eject"
},
"dependencies": {
"expo": "^32.0.0",
"prop-types": "^15.7.2",
"react": "16.5.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
"react-native-animated-hamburger": "0.0.2",
"react-native-drawer": "^2.5.1",
"react-native-elements": "^1.1.0",
"react-native-vector-icons": "^6.4.2",
"react-navigation": "^3.8.1"
},
"devDependencies": {
"babel-preset-expo": "^5.0.0"
},
"private": true
}
As per your code, you are exporting navigation in the wrong way. you should not wrap navigation constant to react component, just export it directly from your js file.
create a route.js file and add your navigation wrapper.
const DrawerNavigator = createDrawerNavigator(
{
Home: {
screen: HomeScreen,
},
About: {
screen: Header2,
},
},
DrawerConfig
);
const MyApp11 = createAppContainer(DrawerNavigator);
export default MyApp11
Now in app.js import it and pass to the component
app.js
import Routes from 'path_to_route_file';
export default class App extends Component{
render(){
return(
<View>
<Routes />
</View>
)