React native tab navigation modal options - react-native

I have my react tab navigation set up in the following way:
export default MainStackScreens = () => {
const MainStack = createBottomTabNavigator();
const screenOptions = ({ route }) => ({
tabBarShowLabel: false,
tabBarIcon: ({ focused }) => {
let iconName = 'home';
switch (route.name) {
case 'Home':
iconName = 'home';
break;
case 'Favorite':
iconName = 'heart';
break;
case 'Filter':
iconName = 'filter';
break;
case 'Profile':
iconName = 'user';
break;
default:
iconName = 'home';
}
if (route.name === 'Post') {
return <AntDesign name='pluscircle' size={42} color={colors.green} />;
}
return (
<FontAwesome
name={iconName}
size={30}
color={focused ? '#1f2833' : '#cacaca'}
/>
);
},
});
return (
<MainStack.Navigator screenOptions={screenOptions}>
<MainStack.Screen name='Home' component={HomeScreen} />
<MainStack.Screen name='Favorite' component={FavoriteScreen} />
<MainStack.Screen name='Post' component={PostScreen} />
<MainStack.Screen name='Filter' component={FilterScreen} />
<MainStack.Screen name='Profile' component={ProfileScreen} />
</MainStack.Navigator>
);
};
Is there a way I can modify this code to have the "Post" route come up as a modal rather than just a normal screen? I've tried several things I found online including splitting the stacks into separate stack groups and fiddling with the screen options but nothing I've done so far seems to have any effect :(
Thanks!

So with some help I got it figured out, it requires some very weird work around using the the listners prop:
return (
<MainStack.Navigator screenOptions={screenOptions}>
<MainStack.Screen name='Home' component={HomeScreen} />
<MainStack.Screen name='Favorites' component={FavoriteScreen} />
<MainStack.Screen
name='Add'
component={PostTab}
listeners={({ navigation }) => ({
tabPress: (event) => {
event.preventDefault();
navigation.navigate('AddModal');
},
})}
/>
<MainStack.Screen name='Search' component={FilterScreen} />
<MainStack.Screen name='Profile' component={ProfileScreen} />
</MainStack.Navigator>
);
};

Related

React native bottom tab bar dynamic loading

I am trying to implement a bottom tab bar with custom tabs. for example, my tab names are a, b, c, and d in some other cases my tab bar names are k, l, m, and n. How to handle this type of scenario. Currently, my component looks like the below. I tried various ways unable to do it. I tried using the map function also it's working.
Tabbar.js
const LoginStack = () => {
return (
<Stack.Navigator>
<Stack.Screen
name="Login"
component={Login}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Home"
component={Home}
options={({ route }) => ({
title: route.params?.title,
headerBackVisible: false,
})}
/>
</Stack.Navigator>
);
};
const Tabs = () => {
return (
<Tab.Navigator
screenOptions={({ route }) => ({
headerShown: false,
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === "LOGIN") {
iconName = focused ? loginAct : loginInAct;
} else if (route.name === "A") {
iconName = focused ? aAct : aInAct;
} else if (route.name === "B") {
iconName = focused ? bAct : bInAct;
} else if (route.name === "C") {
iconName = focused ? bAct : bInAct;
} else if (route.name === "D") {
iconName = focused ? dAct : dInAct;
}
// You can return any component that you like here!
return <Image source={iconName} style={{ width: 20, height: 20 }} />;
},
tabBarActiveTintColor: "#007abc",
tabBarInactiveTintColor: "#000000",
})}
>
<Tab.Screen name="LOGIN" component={LoginStack} />
<Tab.Screen name="A" component={A} />
<Tab.Screen name="B" component={B} />
<Tab.Screen name="C" component={C} />
<Tab.Screen name="D" component={D} />
</Tab.Navigator>
);
};

none of these files exist *node_modules\react-native-vector-icons

//I am customising bottom tab bar but it showing me error that none of these file exist.
const Tab = createBottomTabNavigator();
const Afterreg = () => {
return (
<Tab.Navigator options={({ route }) => ({
tabBarIcon: ({ color }) => {
let iconName;
if (route.name === 'Home') {
iconName = 'home';
} else if (route.name === 'Like') {
iconName = 'search';
} else if (route.name === 'Chat') {
iconName = 'calendar';
} else if (route.name === 'Profile') {
iconName = 'user-o';
}
return <FontAwesome name={iconName} size={25} color={color} />;
},
})}
tabBarOptions={{
activeTintColor: 'selmon',
inactiveTintColor: 'gray',
}}>
<Tab.Screen name="Home" component={Cards} Options={{
tabBarIcon: ({ size, color }) => (
<MaterialCommunityIcons name="home" size={size} color={color} />
),
}} />
<Tab.Screen name="Like" component={Heart} />
<Tab.Screen name="Chat" component={Chat} />
<Tab.Screen name="Profile" component={Profile} />
</Tab.Navigator>
)
}
export default Afterreg;
I am customising bottom tab bar but it showing me error that none of these file exist.

Need help on navigation errors on react native app

I keep getting an error when trying to navigate to Home after register and login. This is the error: The action 'NAVIGATE' with payload {"name":"Home"} was not handled by any navigator. This is how I am navigating to Home after registration: navigation.navigate("Home");
Would love some advice or guidance.
function HomeStack() {
return (
<Stack.Navigator>
<Stack.Screen name="HomeScreen" component={HomeScreen} />
</Stack.Navigator>
);
}
function ProfileStack() {
return (
<Stack.Navigator>
<Stack.Screen name="ProfileScreen" component={ProfileScreen} />
</Stack.Navigator>
);
}
function LeaderboardStack() {
return (
<Stack.Navigator>
<Stack.Screen name="LeaderboardScreen" component={LeaderboardScreen} />
</Stack.Navigator>
);
}
const getPage = (user) => {
if (user) {
return (
<>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
<NavigationContainer>
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: () => {
if (route.name == "Home") {
return <Entypo name="home" size={24} color="black" />;
} else if (route.name == "Leaderboard") {
return (
<MaterialIcons name="leaderboard" size={24} color="black" />
);
} else if (route.name == "Profile") {
return (
<Ionicons name="person-circle" size={24} color="black" />
);
}
},
})}
>
<Tab.Screen
name="Home"
component={HomeStack}
options={{ tabBarLabel: "Home" }}
/>
<Tab.Screen
name="Leaderboard"
component={LeaderboardStack}
options={{ tabBarLabel: "Leaderboard" }}
/>
<Tab.Screen
name="Profile"
component={ProfileStack}
options={{ tabBarLabel: "Profile" }}
/>
</Tab.Navigator>
</NavigationContainer>
</>
)
} else {
return (
<Stack.Navigator>
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="Registration" component={RegistrationScreen} />
</Stack.Navigator>
)
}
}
export default function App() {
const [loading, setLoading] = useState(true);
const [user, setUser] = useState(null);
useEffect(() => {
const usersRef = firebase.firestore().collection("users");
firebase.auth().onAuthStateChanged((user) => {
if (user) {
usersRef
.doc(user.uid)
.get()
.then((document) => {
const userData = document.data();
setLoading(false);
setUser(userData);
})
.catch((error) => {
setLoading(false);
});
} else {
setLoading(false);
}
});
}, []);
if (loading) {
return <></>;
}
return (
<NavigationContainer>
{getPage(user)}
</NavigationContainer>
);
}
There are lots of things happening here, sorry to say but your coding is mess, i can give you example how can manage it cleanly, however all i can see herr is that you tab which contains your homestack and a screen you put in stack above tab both have the same name "Home" change your stack name with homestack and try navigating there..

route.params not returning a variable with React Navigation

I'm attempting to pass a variable from one screen to another using React Navigation's route.params.
I've got this working on the screen immediately preceding it, but it's failing on the next screen and I cannot figure out why.
Here's the code:
setTimeout(() => {
console.log('here is the hid: ' + results.data.hid);
navigation.navigate('MainHome', {
hid: results.data.hid,
});
}, 2500);
The console log is correctly displaying the correct data in the console. This code leads to the next screen:
function Home({route, navigation}) {
const hid = route.params;
const [results, setResults] = useState([]);
const [errorMessage, setErrorMessage] = useState('');
const [loading, setLoading] = useState('loading');
console.log('Here is the hid that is retrieved from the route params on home:' + hid);
This console log is showing the hid as undefined.
Here is the expanded code for the referring screen:
function IntroOne({route, navigation}) {
const [results, setResults] = useState([]);
const [errorMessage, setErrorMessage] = useState('');
const [loading, setLoading] = useState('loading');
const {email, password} = route.params;
const CPRAPI = () => {
api
.get('create_account.php', {
params: {
email: email,
password: password,
},
})
.then(function (response) {
// handle success
setResults(response);
setLoading('success');
})
.catch(function (error) {
// handle error
console.log('ERROR :(');
console.log(error);
setErrorMessage(error);
});
};
useEffect(() => {
CPRAPI();
}, []);
if (loading != 'success') {
return (
<View style={styles.container}>
<Image
style={{width: windowWidth, maxHeight: 250}}
source={require('../components/parallel_universe.jpg')}
/>
<ActivityIndicator size={'large'} color={'#ee1c24'} />
<Text style={styles.header}>Loading...</Text>
</View>
);
} else {
if (results.data.intro_complete == 1) {
setTimeout(() => {
console.log('here is the hid: ' + results.data.hid);
navigation.navigate('MainHome', {
hid: results.data.hid,
});
}, 2500);
return (
<View style={styles.container}>
<Image
style={{width: windowWidth, maxHeight: 250}}
source={require('../components/parallel_universe.jpg')}
/>
<ActivityIndicator size={'large'} color={'#ee1c24'} />
<Text style={styles.header}>Almost Done...</Text>
</View>
);
}
Here is the expanded code for the receiving page:
function Home({route, navigation}) {
const hid = route.params.hid;
const [results, setResults] = useState([]);
const [errorMessage, setErrorMessage] = useState('');
const [loading, setLoading] = useState('loading');
console.log('Here is the hid that is retrieved from the route params on home:' + hid);
const CPRAPI = () => {
api
.get('home.php', {
params: {
hid: hid,
},
})
.then(function (response) {
// handle success
setResults(response);
setLoading('success');
})
.catch(function (error) {
// handle error
console.log('ERROR :(');
console.log(error);
setErrorMessage(error);
});
};
useEffect(() => {
CPRAPI();
}, []);
if (loading == 'loading') {
return (
<View style={styles.container}>
<Image
style={{width: windowWidth, maxHeight: 250}}
source={require('../components/parallel_universe.jpg')}
/>
<ActivityIndicator size={'large'} color={'#ee1c24'} />
<Text style={styles.header}>Loading...</Text>
</View>
);
} else {
return (
<View>
<Header
placement="center"
leftComponent={
<View>
<FontAwesomeIcon
style={{margin: 9}}
icon={['far', 'badge-dollar']}
/>
<Text>{results.data.home_screen[0].firstname}</Text>
</View>
}
centerComponent={{text: 'Hello, ', style: {color: '#fff'}}}
rightComponent={
<FontAwesomeIcon
style={{margin: 9}}
icon={['far', 'question-circle']}
/>
}
/>
<ScrollView>
<View style={styles.container}>
<Image
style={{width: windowWidth, maxHeight: windowHeight / 5}}
source={require('../components/parallel_universe.jpg')}
/>
<Text style={styles.header}>Hello, {}</Text>
<Text style={styles.textSmaller} />
<Text style={styles.textMuchSmaller}>
We will never spam you or sell your email.
</Text>
</View>
</ScrollView>
</View>
);
}
}
Here are my stacks:
const GettingStartedStack = createStackNavigator();
function GettingStartedScreen() {
return (
<GettingStartedStack.Navigator>
<GettingStartedStack.Screen
name="Getting Started"
component={GettingStarted}
options={{headerShown: false}}
/>
<GettingStartedStack.Screen
name="Question One"
component={gs1}
options={{title: 'Your Shadow Self'}}
/>
<GettingStartedStack.Screen
name="Defining Moment Narrative"
component={gs1entry}
/>
<GettingStartedStack.Screen
name="Question Two"
component={gs2}
options={{title: 'Credits & Money'}}
/>
<GettingStartedStack.Screen
name="Define Myself"
component={gs2entry}
options={{title: 'College'}}
/>
<GettingStartedStack.Screen
name="Concentration"
component={gs2Aentry}
options={{title: 'Concentration'}}
/>
<GettingStartedStack.Screen
name="Homeland"
component={gs3}
options={{title: 'Your Homeland'}}
/>
<GettingStartedStack.Screen
name="Choose Homeland"
component={gs3entry}
options={{title: 'Choose Your Homeland'}}
/>
<GettingStartedStack.Screen
name="Citizenship"
component={gs4}
options={{title: 'Your Citizenship'}}
/>
<GettingStartedStack.Screen
name="Choose Citizenship"
component={gs4entry}
options={{title: 'Choose Your Citizenship'}}
/>
<GettingStartedStack.Screen name="Banking" component={gs5} />
<GettingStartedStack.Screen
name="Choose Banking"
component={gs5entry}
options={{title: 'Choose Your Bank'}}
/>
<GettingStartedStack.Screen
name="Luck"
component={gs6}
options={{title: 'Are You Feeling Lucky?'}}
/>
<GettingStartedStack.Screen name="Parents" component={gs7} />
<GettingStartedStack.Screen name="Siblings" component={gs8} />
<GettingStartedStack.Screen name="Inheritance" component={gs9} />
<GettingStartedStack.Screen name="More Credits" component={moreCredits} />
</GettingStartedStack.Navigator>
);
}
const IntroStack = createStackNavigator();
function IntroStackScreen() {
return (
<IntroStack.Navigator>
<IntroStack.Screen
name="Welcome"
component={IntroOne}
options={{headerShown: false}}
/>
<IntroStack.Screen
name="Empire Universe"
component={IntroTwo}
options={{headerShown: false}}
/>
<IntroStack.Screen
name="Shadow Self"
component={IntroThree}
options={{headerShown: false}}
/>
</IntroStack.Navigator>
);
}
const HomeStack = createStackNavigator();
function HomeStackScreen() {
return (
<HomeStack.Navigator>
<HomeStack.Screen
name="Home"
component={Home}
options={{headerShown: false}}
/>
</HomeStack.Navigator>
);
}
const FinancesStack = createStackNavigator();
function FinancesStackScreen() {
return (
<FinancesStack.Navigator>
<FinancesStack.Screen
name="Finances"
component={Finances}
options={{headerShown: false}}
/>
</FinancesStack.Navigator>
);
}
const Tab = createBottomTabNavigator();
function MainTabs() {
return (
<Tab.Navigator
screenOptions={({route}) => ({
tabBarIcon: ({focused, color, size}) => {
let iconName;
if (route.name === 'Cyclopedia') {
iconName = focused ? 'books' : 'books';
} else if (route.name === 'Big Think') {
iconName = focused ? 'head-side-brain' : 'head-side-brain';
} else if (route.name === 'Getting Started') {
iconName = focused ? 'key-skeleton' : 'key-skeleton';
} else if (route.name === 'CSX') {
iconName = focused ? 'chart-area' : 'chart-area';
} else if (route.name === 'Marketwire') {
iconName = focused ? 'analytics' : 'analytics';
} else if (route.name === 'Login') {
iconName = focused ? 'user-cog' : 'user-cog';
} else if (route.name === 'Map') {
iconName = focused ? 'map' : 'map';
} else if (route.name === 'Intro') {
iconName = focused ? 'home' : 'home';
} else {
iconName = focused ? 'books' : 'books';
}
// You can return any component that you like here!
return <FontAwesomeIcon icon={['far', iconName]} />;
},
})}
tabBarOptions={{
activeTintColor: 'tomato',
inactiveTintColor: 'gray',
}}>
<Tab.Screen name="Home" component={HomeStackScreen} />
<Tab.Screen name="Finances" component={FinancesStackScreen} />
</Tab.Navigator>
);
}
const MainStack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<MainStack.Navigator>
<MainStack.Screen
name="Welcome"
component={IntroStackScreen}
options={{headerShown: false}}
/>
<MainStack.Screen
name="MainHome"
component={MainTabs}
options={{headerShown: false}}
/>
<MainStack.Screen
name="Getting Started"
component={GettingStartedScreen}
options={{headerShown: false}}
/>
</MainStack.Navigator>
</NavigationContainer>
);
}
Any thoughts about what could be causing this? I've tried a bunch of things, but just can't seem to get it to resolve properly.
I'm using:
React Native - 0.63.4
"#react-navigation/bottom-tabs": "^5.11.7",
"#react-navigation/native": "^5.9.2",
"#react-navigation/stack": "^5.14.1",
Thanks in advance!
In react-navigation 5 ... we need to specify what screen you wanna navigate to in case of nested-navigators...
Try this:
navigate('MainHome', {
screen: Home,
params: {
screen: 'Home',
params: {
hid: results.data.hid,
},
},
});
This will work.
function Home({route, navigation}) {
const hid = route.params.hid;
const [results, setResults] = useState([]);
const [errorMessage, setErrorMessage] = useState('');
const [loading, setLoading] = useState('loading');
console.log('Here is the hid that is retrieved from the route params on home:' + hid);

Hide specific Tab.Screen in Tab.Navigator React Native

Is there a way where I could hide the screen that says "### HIDE ME ###" or is there a way where I could define a screen that wont show up in the Tab Navigation?
Here is the code:
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === 'Home') {
iconName = focused
? 'ios-home'
: 'ios-home';
} else if (route.name === 'Messages') {
iconName = focused ? 'ios-paper-plane' : 'ios-paper-plane';
} else if (route.name === 'Todo') {
iconName = focused ? 'ios-list-box' : 'ios-list';
} else if (route.name === 'More') {
iconName = focused ? 'ios-more' : 'ios-more';
} else if (route.name === 'Videos') {
iconName = focused ? 'ios-videocam' : 'ios-videocam';
}
// You can return any component that you like here!
return <Ionicons name={iconName} size={size} color={color} />;
},
})}
tabBarOptions={{
activeTintColor: '#ffcc07',
inactiveTintColor: 'gray',
}}>
<Tab.Screen name="Home" component={DashboardScreen} />
<Tab.Screen name="Messages" component={MessagesScreen} />
<Tab.Screen name="Todo" component={TodoScreen} />
<Tab.Screen name="Videos" component={WisdomReplayScreen} />
<Tab.Screen name="More" component={MoreOptionsScreen} />
<Tab.Screen name="Test" component={Test} ### HIDE ME ###/>
</Tab.Navigator>
you can determine the screens on which the tab bar should be hidden like this
function getTabBarVisible(route) {
const routeName = route.state
? route.state.routes[route.state.index].name
: route.params?.screen || 'Home';
if (routeName === 'Home') {
return false;
}
return true;
}
**and attach it to the tab navigator's screen:**
<Tab.Screen name="Home"
component={HomeStackScreen}
options={({ route }) => ({
tabBarVisible: getTabBarVisible(route) })} />