I am a beginner in React Native and I want to create the following project:
I have a component called MainContainer, which is a NavigationContainer (Tab.Navigator) with several Tab.Screen components: Home, MenuForTeacher, ScanCode, and Settings.
Within MenuForTeacher, there is another Tab.Navigator, this time using material-top-tabs, with two Tab.Screen components: homeStack and AddForAllClasses.
Inside homeStack, there is a react-navigation-stack with two screens: AddForTeacher (the default screen) and ClassName. I want to add a button in AddForTeacher, so that when it is tapped, ClassName will appear.
I implemented this design because ClassName shouldn’t be part of the MainContainer. Therefore, it doesn’t have the bottom navigation bar but instead, in the header, only a ‘button’ allowing users to navigate back to the AddForTeacher screen.
The issue is :
ERROR Error: This navigator has both navigation and container props, so it is unclear if it should own its own state. Remove props: "route" if the navigator should get its state from the navigation prop. If the navigator should maintain its own state, do not pass a navigation prop.
*** This project is for learning in React Native, so feel free to provide any critiques. I’m open to feedback as it helps me learn more about this framework.
MainContainer
import {NavigationContainer} from '@react-navigation/native';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import Icon from 'react-native-vector-icons/Ionicons';
import React,{useContext} from 'react';
import Home from './screens/Home';
import Settings from './screens/Settings';
import ScanCode from './screens/ScanCode';
import {AuthContext} from '../App';
import MenuForTeacher from './screens/screensForTeacher/MenuForTeacher';
const homeName = 'Home';
const settingsName = 'Settings';
const scanCodeName = 'ScanCode';
const menuForTeacher = 'Menu';
const Tab = createBottomTabNavigator();
function MainContainer() {
const {user} = useContext(AuthContext);
//const [email, setEmail] = React.useState(Email);
//console.log("email in MainContainer"+email)
return (
<>
{console.log("maincontainer user"+user)}
<NavigationContainer>
<Tab.Navigator
initialRouteName={homeName}
screenOptions={({route}) => ({
tabBarIcon: ({focused, color, size}) => {
let iconName;
if (route.name === homeName) {
iconName = focused ? 'home' : 'home-outline';
} else if (route.name === settingsName) {
iconName = focused ? 'settings-sharp' : 'settings-outline';
} else if (route.name === scanCodeName) {
iconName = focused ? 'scan' : 'scan';
}
else if (route.name === menuForTeacher && user==="teacher") {
iconName = focused ? 'school' : 'school';
}
return <Icon name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: '#1A3C40',
tabBarInactiveTintColor: 'gray',
headerShown: route.name !== homeName ? true : false,
headerTintColor: '#EDE6DB',
headerStyle: {
backgroundColor: '#1D5C63',
},
})}>
<Tab.Screen name={homeName} component={Home} />
{(user==="teacher")?
(<Tab.Screen name={menuForTeacher} component={MenuForTeacher} />)
:null}
<Tab.Screen name={scanCodeName} component={ScanCode} />
<Tab.Screen name={settingsName} component={Settings} />
</Tab.Navigator>
</NavigationContainer>
</>
);
}
export default MainContainer
MenuForTeacher
import {NavigationContainer} from '@react-navigation/native';
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
import Icon from 'react-native-vector-icons/Ionicons';
import React,{useContext} from 'react';
import {AuthContext} from '../../../App';
import NavigatorAddForTeacher from "./homeStack";
import AddForAllClasses from "./AddForAllClasses";
const addForTeacher = 'My classes';
const addForAllClasses = 'All classes';
const Tab = createMaterialTopTabNavigator();
function MenuForTeacher() {
const {user} = useContext(AuthContext);
return (
<>
<Tab.Navigator
initialRouteName={addForTeacher}
screenOptions={() => ({
tabBarActiveTintColor: '#1A3C40',
tabBarInactiveTintColor: 'gray',
})}>
<Tab.Screen name={addForTeacher} component={NavigatorAddForTeacher} />
<Tab.Screen name={addForAllClasses} component={AddForAllClasses} />
</Tab.Navigator>
</>
);
}
export default MenuForTeacher;
homeStack
import { createStackNavigator } from 'react-navigation-stack';
import { createAppContainer} from 'react-navigation';
import AddForTeacher from './AddForTeacher';
import ClassName from './ClassName';
const screens ={
AddForTeacher:{
screen: AddForTeacher
},
ClassName:{
screen: ClassName
}
};
const HomeStack = createStackNavigator(screens);
export default createAppContainer(HomeStack);
AddForTeacher
import {
Text, View,StyleSheet,TouchableOpacity,ScrollView
} from 'react-native';
import API_BASE_URL from '../../../../config';
import {AuthContext} from '../../../App';
import React,{useContext, useEffect,useState} from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
import Icon from 'react-native-vector-icons/Ionicons';
const AddForTeacher = ({navigation}) =>{
const {setClassSelectByTeahcer} = useContext(AuthContext);
const {classSelectByTeahcer} = useContext(AuthContext);
const {email} = useContext(AuthContext);
const [classes,setClasses] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const getJwtTokenFromAsyncStorage = async () => {
...
};
const fetchClass = async () =>{
...
}
const handleClassNamePress = (item) => {
navigation.navigate('ClassName');
};
useEffect(() => {
if (isLoading) {
fetchClass();
}
}, [isLoading]);
return (
<>
<ScrollView style={styles.contanerClasses}>
{classes.map((item, index) => (
<View key={item.NomeClasse} style={styles.contanerClass}>
<View style={styles.eatchClass}>
<Text>{item.NomeClasse}</Text>
</View>
<View style={styles.horizontalLine} />
<View style={styles.content}>
<TouchableOpacity
onPress={() => handleClassNamePress(item.NomeClasse)}
// style={}
>
<View style={styles.buttonAdd}>
<Icon name={'add-outline'} size={24} />
</View>
</TouchableOpacity>
</View>
</View>
))}
</ScrollView>
</>
);
}
const styles = StyleSheet.create({
content:{
},
horizontalLine: {
height: 2,
backgroundColor: 'black',
marginVertical: 10,
marginLeft:5,
marginRight:5,
},
contanerClass:{
padding:10,
margin:10,
borderColor: 'black',
borderRadius: 20,
borderWidth: 1,
},
contanerClasses:{
margin:10,
},
eatchClass:{
// borderColor: 'black',
//borderRadius: 20,
//borderWidth: 1,
//borderBottomWidth: StyleSheet.hairlineWidth,
//width:"80%",
}
})
export default AddForTeacher;
ClassName
import { de } from "date-fns/locale"
import { Text } from "react-native"
const ClassName = () =>{
//const { name } = navigation.params;
return (
<View >
<Text>{"hello"}</Text>
</View>
);
}
export default ClassName;