Screen not loading when trying to navigate between screens - react-native

I'm trying to navigate between 7 screens in react native and when I load my code the screens show up blank. I don't know if there's a problem inside my app.js file or whether it's in the login screen file. I'm trying to create a social media app with react native which should in turn navigate between all of these screens without any errors.
My App.js file is:
import home from "./screens/home";
import explore from "./screens/explore";
import createpost from "./screens/createpost";
import messages from "./screens/messages";
import profile from "./screens/profile";
import settings from "./screens/settings";
import login from "./screens/login";
import { NavigationContainer } from "#react-navigation/native";
import { createStackNavigator } from "#react-navigation/native-stack";
const Stack = createNativeStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="login"
component={login}
options={{title: "Welcome"}}
/>
<Stack.Screen
name="home"
component={home}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
My login screen file is:
import { NavigationContainer } from '#react-navigation/native';
import { StatusBar } from 'expo-status-bar'
import { StyleSheet, Text, View, Button } from 'react-native';
export default function login() {
return (
<View style={styles.container}>
<Button title="Navigate to second screen with french"
onPress={() => navigation.navigate("explore", { language: "french"})}
/>
<Button title="Navigate to second screen with english"
onPress={() => navigation.navigate("explore", { language: "french"})}
/>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});

You should add the pages you want to
navigate to in your stack as you did with login and home.
<Stack.Navigator>
<Stack.Screen
name="login"
component={login}
options={{title: "Welcome"}}
/>
<Stack.Screen
name="home"
component={home}
/>
<Stack.Screen
name="explore"
component={explore}
/>
...
</Stack.Navigator>
Then
navigation.navigate('explore', {...});
should work.

Related

Correct way of presenting a new screen with a stack?

I have a signup page with 4 steps (4 separate screens). On the first page, the user enters their username in a field, on the second page a display name, on the third their birthday, and on the fourth their password.
Here's my current signup screen file:
import React from 'react';
import { View, Text, Button } from 'react-native';
const SignupScreen = () => {
return (
<View>
<Text>First step</Text>
<Button
title="Next step"
/>
</View>
);
}
export default SignupScreen;
But I'm a bit confused as to how to present the next screen when the user taps the Button. How do I create a Stack here? Or would I do it in the App.js file?
Here is my App.js:
import { StatusBar } from 'expo-status-bar';
import { FlatList, StyleSheet, Text, View, TouchableHighlight } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import {
RootStack,
TabsStack,
SignupStack
} from './navigation/navigation';
export default function App() {
return (
<NavigationContainer>
<RootStack.Navigator>
<RootStack.Screen
name="Tabs"
options={{ headerShown: false }}
component={TabsStack}
/>
<RootStack.Screen
name="SignupStack"
options={{ headerShown: false }}
component={SignupStack}
/>
</RootStack.Navigator>
</NavigationContainer>
);
}
And here is my navigation.js file:
import React from 'react';
import { FlatList, StyleSheet, Text, View, TouchableHighlight } from 'react-native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import SignupScreen from '../screens/SignupScreen';
export const RootStack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();
const SignupNav = createNativeStackNavigator();
export const TabsStack = () => (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="History" component={SecondScreen} />
<Tab.Screen name="Third" component={ThirdScreen} />
<Tab.Screen name="Fourth" component={FourthScreen} />
</Tab.Navigator>
);
export const SignupStack = () => (
<SignupNav.Navigator>
<SignupNav.Screen
name="Signup"
component={SignupScreen}
options={{ headerTitle: 'Sign up' }}
/>
</SignupNav.Navigator>
);
function HomeScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home</Text>
</View>
);
}
function SecondScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Second</Text>
</View>
);
}
function ThirdScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Third</Text>
</View>
);
}
function FourthScreen({ navigation }) {
function onPressButton() {
navigation.navigate('SignupStack');
}
return (
<View>
<FlatList
data={[
{key: 'Signup'},
]}
renderItem={({item}) => <TouchableHighlight onPress={onPressButton} underlayColor="white"><Text>{item.key}</Text></TouchableHighlight>}
/>
</View>
);
}
What's the correct way of doing this?
Thank you
the best way that i know, make all the screen as component and import it in the signup screen
signup.js
/*
import all you component(pages) here...
*/
const [screen, setScreen] = useState(1)
{screen == 1 ? (
<ScreenOne
onNext={()=>setScreen(2)}
/>
) : screen == 2 ? (
<ScreenTwo
onNext={()=>setScreen(3)}
/>
) : screen == 3 ? (
<ScreenThree
onNext={()=>setScreen(4)}
/>
)
}
You can pass all your state and callback function from signup page to all the component get value from the component

Screen title not centered

This is my HomeScreen.js:
import * as React from 'react';
import HomeScreenStyle from '../styles/ScreenStyles';
import { View, TouchableOpacity, Text, Image, StyleSheet } from 'react-native';
const HomeScreen = ({ navigation }) => {
return (
<View style={HomeScreenStyle.container}>
<Image source = {require("../assets/AppLogo.jpg")}/>
</View>
);
};
export default HomeScreen;
This is my HomeScreenStyle.js
import { StyleSheet } from 'react-native';
const HomeScreenStyle = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
export default HomeScreenStyle;
And this is my navigator which configures the title:
import * as React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import HomeScreen from '../screens/HomeScreen'
const Stack = createNativeStackNavigator();
const MyStack = () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ title: 'Home' }}
/>
</Stack.Navigator>
</NavigationContainer>
);
};
export default MyStack;
As you can see in the photo the screen title is not centered, how can I achieve that?
thank you
Add the following headerTitleAlign: 'center' in the options so the stack screen will be
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ title: 'Home',headerTitleAlign: 'center' }}
/>
just add headerTitleAlign:'center' to screen options :
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ title: 'Home',headerTitleAlign:'center' }}
/>

Bottom tab bar should not occur anywhere but only on the first initial screen that renders via Webview in React Native

I have a webview component in my project, where the flow being =>
The bottomTabBar opens the initial screen of the url that is given to Webview source prop, which should remain, when any link is clicked on the webview and it moves to another screen, the bottomtabbar should not come up.
Below is my WebviewScreen code :
import React, {Component} from 'react';
import {WebView} from 'react-native-webview';
import {View, SafeAreaView, ActivityIndicator} from 'react-native';
export default class ConsultationHomeScreen extends Component {
renderLoadingView = () => {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<ActivityIndicator size="large" />
</View>
);
};
render() {
const {url} = this.props.route.params;
return (
<SafeAreaView style={{flex: 1}}>
<WebView
source={{uri: url}}
renderLoading={this.renderLoadingView}
startInLoadingState={true}
ref={(ref) => {
this.webview = ref;
}}
onNavigationStateChange={(event) => {
if (event.url !== url) {
this.webview.stopLoading();
}
}}
/>
</SafeAreaView>
);
}
}
And Appnavigation.js
import * as React from 'react';
import {NavigationContainer} from '#react-navigation/native';
import {createStackNavigator} from '#react-navigation/stack';
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
import LoginScreen from '../screens/authentication/LoginScreen';
import OtpScreen from '../screens/authentication/OtpScreen';
import AddChild from '../screens/Child/AddChild';
import AcceptInviteScreen from '../screens/AcceptInviteScreen';
import ConsultationHomeScreen from '../screens/ConsultationHomeScreen';
import HomeScreen from '../screens/HomeScreen/HomeScreen';
import PlansScreen from '../screens/PlansScreen';
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();
function BottomTabBar() {
return (
<Tab.Navigator
lazy={false}
tabBarOptions={{
labelStyle: {
color: '#FF1493',
fontSize: 15,
},
}}>
<Tab.Screen
name="Home"
component={HomeScreen}
options={{
tabBarIcon: () => {
<MaterialIcon name="home" color="#FF1493" size={20} />;
},
}}
/>
<Tab.Screen
name="Consult"
component={ConsultationHomeScreen}
initialParams={{
url: 'some link',
}}
/>
<Tab.Screen name="Plans" component={PlansScreen} />
</Tab.Navigator>
);
}
export default function AppNavigation() {
return (
<NavigationContainer>
<Stack.Navigator headerMode="none">
<Stack.Screen name="login" component={LoginScreen} />
<Stack.Screen name="otp" component={OtpScreen} />
<Stack.Screen name="addchild" component={AddChild} />
<Stack.Screen
name="acceptinvitescreen"
component={AcceptInviteScreen}
/>
<Stack.Screen name="home" component={BottomTabBar} />
</Stack.Navigator>
</NavigationContainer>
);
}
However, am unable to remove the bottomtabbar,could anyone please suggest how should I implement this behaviour?
Step1-> Webview initial screen renders and has bottomtabtabr
Step2-> Link clicked on the initial screen and navigates to next screen handled by web source
Step3->Bottom tab bar should not occur anywhere but only on the first initial screen
Please,any suggestion would be appreciated and let me know if anything else is required for better understanding.
I tested this modification in your source code and it works like a charm.
GIT difference in WebviewScreen.js :
## -23,6 +23,7 ## export default class ConsultationHomeScreen extends Component {
}}
onNavigationStateChange={(event) => {
if (event.url !== url) {
+ this.props.navigation.setOptions({ tabBarVisible: false });
this.webview.stopLoading();
}
}}
Let me know if you have any issue.

React Native - Update text after clicking button

I want to update the text after clicking button.
But couldn't find a way to do this.
The code is like:
import * as React from 'react';
import { View, Button, Text } from 'react-native';
import { NavigationContainer, CommonActions } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
function HomeScreen({ navigation }) {
const state = {
user: 'test',
};
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>{state.user}'s profile</Text>
<Button
title="Change user param"
onPress={() =>
navigation.dispatch({
...CommonActions.setParams({ user: 'Wojtek' }),
})
}
/>
</View>
);
}
const Stack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
Expo example
I've tried navigation.setParams() and this.setState(), they couldn't work with the code I attached above.
You have to use hooks in functional components. So the code would be something like this:
import * as React from 'react';
import { View, Button, Text } from 'react-native';
import { NavigationContainer, CommonActions } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
function HomeScreen({ navigation }) {
const [user, setUser] = React.useState('test');
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>{user}'s profile</Text>
<Button
title="Change user param"
onPress={() => setUser("keidakira") }
/>
</View>
);
}
const Stack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
Check it's working at Expo Link

Setting up customizable Header in React Native

I wish to create Header for my Notes Storage App on React Native. I have Tried using stackNavigator till now but I am caught up on how to add menu icon which onPres will open the Drawer. I tried using HeaderLeft in stackDesignHead but it gives an error. Also using a FAB is not recommended.
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import HomePage from './src/HomePage/HomePage';
import NotesFolder from './src/notes';
import CreateNewFolder from './src/CreateNewFolder';
import Icon from 'react-native-vector-icons/Ionicons';
import Constants from 'expo-constants';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createDrawerNavigator } from '#react-navigation/drawer';
const Drawer = createDrawerNavigator();
const Stack = createStackNavigator();
const stackDesignHead = {
title: "Notes Classifier",
headerTintColor:"white",
headerStyle:{
backgroundColor:"#fcba03"
},
headerTitleStyle: {
fontWeight: 'bold',
},
headerTitleAlign: 'center'
}
function LeftDrawer () {
return(
<Stack.Navigator>
<Stack.Screen
name="HomePage"
component={HomePage}
options={stackDesignHead}
/>
<Stack.Screen
name="NotesFolder"
component={NotesFolder}
options={{...stackDesignHead,title:"Notes"}}
/>
<Stack.Screen
name="CreateNewFolder"
component={CreateNewFolder}
options={{...stackDesignHead,title:"+ new Folder"}}
/>
</Stack.Navigator>
)
}
const menuDesignHead = {
title: "Notes Classifier",
headerTintColor:"white",
headerStyle:{
backgroundColor:"#fcba03"
},
headerTitleStyle: {
fontWeight: 'bold',
},
headerTitleAlign: 'center'
}
function App () {
return(
<View style={styles.container}>
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen
name="Home"
component={LeftDrawer}
options={{menuDesignHead}}
/>
</Drawer.Navigator>
</View>
);
}
export default()=>{
return(
<NavigationContainer>
<App/>
</NavigationContainer>
)
}
I am new to react native and unaware of various ways to create header.
Provides a way to create your own custom headers in React-navigation documents.
Replacing the title with a custom component
Sometimes you need more control than just changing the text and styles of your title -- for example, you may want to render an image in place of the title, or make the title into a button. In these cases you can completely override the component used for the title and provide your own.
Example
function LogoTitle() {
return (
<Image
style={{ width: 50, height: 50 }}
source={require('#expo/snack-static/react-native-logo.png')}
/>
);
}
function StackScreen() {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ headerTitle: props => <LogoTitle {...props} /> }}
/>
</Stack.Navigator>
);
}