Bottom Navigation TabBarIcon render method is wrong? - javascript

I tried to create bottom Navigation,
Following this link : https://reactnavigation.org/docs/tab-based-navigation/#customizing-the-appearance
and here is my code :
import React from "react";
import { createBottomTabNavigator } from "#react-navigation/bottom-tabs";
import Ionicons from "react-native-vector-icons";
// Screens
import Home from "./Home";
import Settings from "./Settings";
const Tab = createBottomTabNavigator();
function MainContainer({ navigation }) {
return (
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === "Home") {
iconName = focused
? "ios-information-circle"
: "ios-information-circle-outline";
} else if (route.name === "Settings") {
iconName = focused ? "ios-list-box" : "ios-list";
}
return <Ionicons name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: "tomato",
tabBarInactiveTintColor: "gray",
})}
>
<Tab.Screen name="Home" component={Home} />
<Tab.Screen name="Settings" component={Settings} />
</Tab.Navigator>
);
}
export default MainContainer;
But I got this error :
Error: 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's defined in, or you might have mixed up default and named imports.
Check the render method of `TabBarIcon`.
I found out the mistake,
on the
import Ionicons from "react-native-vector-icons"; it should have been import Ionicons from "react-native-vector-icons/Ionicons"

Solutions:
You need wrap your <Tab.Navigator> into root navigation container
Example:
You need to first install dependency of #react-navigation/native
import {NavigationContainer} from '#react-navigation/native';
import {createStackNavigator} from '#react-navigation/stack';
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();
const MainContainer = () => {
return (
<NavigationContainer>
<Tab.Navigator />
<Stack.Navigator />
...other your navigation
</NavigationContainer>
);
};
You can checkout react-navigaiton https://reactnavigation.org/docs/getting-started/

Just wrape your <Tab.Navigator> in <NavigationContainer>
import React from "react";
import { NavigationContainer } from '#react-navigation/native'
//Reset Imports
const Routes = () => {
return (
<NavigationContainer>
<Tab.Navigator>
</Tab.Navigator>
</NavigationContainer>
)
}
export default Routes

Related

React navigator not moving between screens

My app closes when I press the switch screen button. I don't see any error output.
I did a version check and there was no problem.
The function I wrote for the button works
Router.js
import React from "react";
import { NavigationContainer } from "#react-navigation/native";
import { createNativeStackNavigator } from "#react-navigation/native-stack";
import First from "./First";
import Second from "./Second";
const Stack = createNativeStackNavigator();
const Router = () =>{
return(
<NavigationContainer>
<Stack.Navigator initialRouteName="First">
<Stack.Screen name="First" component={ First }/>
<Stack.Screen name="Second" component={ Second }/>
</Stack.Navigator>
</NavigationContainer>
);
}
export default Router;
First.js
import React from 'react';
import {View,Text,Button} from 'react-native';
const First = ( props ) =>{
const gotoSecond = () => {
console.log("First");
props.navigation.navigate("Second");
console.log("second")
}
return (
<View>
<Text>Hello First Page!</Text>
<Button title="Go SecondPage!" onPress={gotoSecond}/>
</View>
);
};
export default First;
Second.js
import React from 'react';
import {View,Text} from 'react-native';
const Second = () =>{
return (
<View>
<Text>Hello Second Page!</Text>
</View>
);
};
export default Second;
OS:Android,
Emulator:Genymotion.
Now I'm using ADV instead of Genymotion, problem solved.

Undefined is not an object (evaluating 'navigation.navigate') when trying to navigate between two sites React Native

I try to navigate between two pages in a React Native app. I keep getting errors for my implementations but I don't know why.
I have the following setup for a "Home" and "Settings" site in the React Native app with Navigator adjusted from the documentation:
App.js
import Home from "./Home";
import { NavigationContainer } from '#react-navigation/native';
export default function App() {
return <NavigationContainer><Home/></NavigationContainer>
}
Home.jsx
const Home = ({ navigation }) => {
return (
<View style={["some style...", {}]}>
<View style={["some style..."]}>
<TouchableOpacity onPress={() =>
navigation.navigate('Settings')}>
<Image "some image..."/>
</TouchableOpacity>
</View>
</View>
Settings.jsx
A component which should be rendered.
MyStack.jsx
import * as React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import Home from './Home';
import Settings from './Settings';
const Stack = createNativeStackNavigator();
const MyStack = () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={Home}
/>
<Stack.Screen name="Settings" component={Settings} />
</Stack.Navigator>
</NavigationContainer>
);
};
I get undefined is not an object (evaluating 'navigation.navigate'). Also adding this.props to navigation.navigate('Settings') throws and error. I am just not able to access my Navigator.
You seem to be setting up a navigator but never using it, since in App.js you are just calling <Home/>.
Change App.js to this:
import MyStack from "./MyStack"; // Use the correct path for the import
export default function App() {
return <MyStack/>
}
Add at the end of MyStack.jsx:
export default MyStack;

How to remove default styles from react-navigation?

I was making an app with react native and react-navigation. So what I did was I made a Login screen. Then I used react-navigation to create a native stack navigator and linked it to my Login screen. I successfully rendered the Login Screen but there seems to be some sort of default styling on the stack navigator(?). How do I remove or overwrite those styles so that the original styling of my screens come back? Images and Code below.
This is the stack navigator
import React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import LoginScreen from '../screens/LoginScreen';
import SignUpScreen from '../screens/SignUpScreen';
const Stack = createNativeStackNavigator();
const AuthStack = () => {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Login" screenOptions={{ header: () => null }}>
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="Signup" component={SignUpScreen} />
</Stack.Navigator>
</NavigationContainer>
);
};
export default AuthStack;
When I only render the LoginScreen it looks like this
When I use AuthStack it looks like this
Should have read the docs nicely it was there in the NativeStackNavigator options.
import React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import LoginScreen from '../screens/LoginScreen';
import SignUpScreen from '../screens/SignUpScreen';
const Stack = createNativeStackNavigator();
const AuthStack = () => {
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName="Login"
screenOptions={{
headerShown: false,
header: () => null,
contentStyle: { backgroundColor: 'white' },
}}
>
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="Signup" component={SignUpScreen} />
</Stack.Navigator>
</NavigationContainer>
);
};
export default AuthStack;
To do your own style do this
import { createStackNavigator } from "#react-navigation/stack";
import { NavigationContainer, DefaultTheme } from "#reactnavigation/native";
const MyTheme = {
...DefaultTheme,
colors: {
...DefaultTheme.colors,
background: Color.red,
},
};
Then do this
<NavigationContainer theme={MyTheme}>
<Stack.Navigator initialRouteName="startscreen" headerMode="none" >
</Stack.Navigator>
</NavigationContainer>
More information here (https://reactnavigation.org/docs/themes/)

How to display a nested screen within another nested screen?

My app is currently set up as follows, and I want to show the Hub screen when the user presses on Study:
App.js:
import React, { Component } from 'react';
...
import { View } from 'react-native'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware } from 'redux'
import rootReducer from './redux/reducers'
import thunk from 'redux-thunk'
const store = createStore(rootReducer, applyMiddleware(thunk))
...
export class App extends Component {
...
render() {
return (
<Provider store={store}>
<NavigationContainer>
<Stack.Navigator initialRouteName="Main">
<Stack.Screen name="Main" component={MainScreen} options={{ headerShown: false }}/>
</Stack.Navigator>
</NavigationContainer>
</Provider>
)
}
}
export default App
Main:
import React, { Component } from 'react'
import { View } from 'react-native'
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { fetchUser, clearData } from '../redux/actions/index'
import ProfileScreen from './main/Profile'
import HomeScreen from './main/Home'
import StudyScreen from './main/Study'
import TestScreen from './main/Test'
import { createMaterialBottomTabNavigator } from '#react-navigation/material-bottom-tabs'
const Tab = createMaterialBottomTabNavigator();
// https://reactnavigation.org/docs/bottom-tab-navigator/
export class Main extends Component {
componentDidMount() {
this.props.clearData();
this.props.fetchUser();
}
render() {
...
return (
<Tab.Navigator initialRouteName="Home" activeColor="#f0edf6" barStyle={{ backgroundColor: '#694fad' }} shifting='true'>
<Tab.Screen name="Home" component={HomeScreen}
options={{
tabBarLabel: 'Home', tabBarColor: '#FF6347', tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="home" color={color} size={26}/>
),
}} />
<Tab.Screen name="Study" component={StudyScreen}
options={{
tabBarLabel: 'Study', tabBarColor: '#694FAD', tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="school" color={color} size={26}/>
),
}} />
<Tab.Screen name="Profile" component={ProfileScreen}
options={{
tabBarLabel: 'Profile', tabBarColor: '#1F65FF', tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="account" color={color} size={26}/>
),
}} />
<Tab.Screen name="Test" component={TestScreen}
options={{
tabBarLabel: 'Test', tabBarColor: '#3490AA', tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="history" color={color} size={26}/>
),
}} />
</Tab.Navigator>
)
}
}
const mapStateToProps = (store) => ({
currentUser: store.userState.currentUser
})
const mapDispatchProps = (dispatch) => bindActionCreators({fetchUser, clearData}, dispatch)
export default connect(mapStateToProps, mapDispatchProps)(Main);
Study:
import React, { Component } from 'react'
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
const Stack = createStackNavigator();
import HubScreen from './studyWebviews/Hub'
export class Study extends Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Hub">
<Stack.Screen name="Hub" component={HubScreen} options={{ headerShown: false }}/>
</Stack.Navigator>
</NavigationContainer>
);
}
}
Hub:
import React from 'react'
import { Text } from 'react-native'
export default function Hub() {
return (
<Text>Hub</Text>
)
}
Trying to load my app gives this error:
×
Error: Couldn't find a 'component', 'getComponent' or 'children' prop for the screen 'Study'. 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.
How do I fix this? Please let me know if I need to clarify anything or make any changes for the sake of readability, thank you.
I believe you are importing the components incorrectly, as the message suggests: "...or mixed up default import and named import when importing."
Try export default class Study...

How do I properly define screens for React Native Navigation? (Error: Couldn't find any screens for the navigator. Have you defined any screens...)

First off I have looked at Error: Couldn't find any screens for the navigator. Have you defined any screens as its children?
And that person had an array of screens that was not yet filled. I have defined my screens and using them directly.
I'm new to React Native, and I'm trying to add navigation to the basic template. It's not going well.
My code is as follows:
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* #format
* #flow strict-local
*/
import React from 'react';
import type {Node} from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import {
SafeAreaView,
ScrollView,
StatusBar,
StyleSheet,
Text,
useColorScheme,
View,
Button,
} from 'react-native';
const Stack = createStackNavigator();
const HomeScreen = ({ navigation }) => {
return (
<Button
title="Go to Jane's profile"
onPress={() =>
navigation.navigate('Profile', { name: 'Jane' })
}
/>
);
};
const ProfileScreen = ({ navigation, route }) => {
return <Text>This is {route.params.name}'s profile</Text>;
<Button
title="Go to Home"
onPress={() =>
navigation.navigate('Home')
}
/>
};
const App: () => Node = () => {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ title: 'Welcome' }}
key="1"
/>
<Stack.Screen name="Profile" component={ProfileScreen} key='2' />
</Stack.Navigator>
</NavigationContainer>
);
};
export default App;
At which point I get the error:
Error: Couldn't find any screens for the navigator. Have you defined any screens as its children?
I assume there's something basic I'm missing.
the component that is your screen need to return only one element.
If you need to return more than one element you can wrap it in the <> </> balise or any other component.
const ProfileScreen = ({ navigation, route }) => {
return (
<>
<Text>This is {route.params.name}'s profile</Text>
<Button title="Go to Home" onPress={() => navigation.navigate('Home')} />
</>
);
};

Categories

Resources