Navigation with UseNavigation() - javascript

I am having some trouble understanding the use of UseNavigation. I couldn't find a lot of good examples either. I have this one example where the first button takes us to the Registration Page but I am not sure how exactly. I am trying to edit it in a way that the second button takes me to my login page.
This is my home page:
import Login from './login/Login'
type HomeScreenProps = {};
export const HomeScreen = observer<HomeScreenProps>(() => {
const navigation = useNavigation();
const appStore = useAppStore();
return (
<View style={styles.page}>
<View style={styles.container}>
<Hello />
<Button onPress={() => appStore.hello()}>
<Text>Change State</Text>
</Button>
<Text>The state can also be here: </Text>
<Text>{appStore.helloWorld}</Text>
{/* */}
<Button
onPress={() => navigation.navigate('Registration')}>
<Text>Press to register</Text>
</Button>
<Button
//onPress={() => navigation.navigate('Login')}
>
<Text>Login</Text>
</Button>
</View>
</View>
);
});
Here is the architecture of my login page:
import React, { Component } from 'react';
import { Container, Header, Left, Body, Right, Button, Title, Text, Form, Item, Input, Label} from 'native-base';
import { StackNavigator } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import { DrawerNavigator } from "react-navigation";
import { createAppContainer } from 'react-navigation';
export class Login extends Component {
constructor(props) {
super(props);
this.state = {
username: '',
password: '',
};
}
render() {
return (
<Container>
<Text >Instaride</Text>
<Form>
<Item floatingLabel>
<Label onChangeText={(text) => this.setState({username: text})}>Username</Label>
<Input
value={this.state.username}
onChangeText={username => this.setState({ username })}
placeholder={'Username'}
/>
</Item>
<Item floatingLabel last>
<Label >Password</Label>
<Input
value={this.state.password}
onChangeText={password => this.setState({ password })}
placeholder={'Password'}
secureTextEntry={true}
/>
</Item>
</Form>
<Left>
<Button onPress={() => this.props.navigation.navigate("Details")}>
<Text>Login</Text>
</Button>
<Text >Forgot Password?</Text>
</Left>
<Right>
<Button hasText transparent>
<Text>Sign Up Here</Text>
</Button>
</Right>
</Container>
);
}
}
class DetailsScreen extends React.Component {
render() {
return (
<Text>Details Screen</Text>
);
}
}
class RegisterationScreen extends React.Component {
render() {
return (
<Text>sign up time</Text>
);
}
}
const LoginRouter = createStackNavigator(
{
Home: { screen: Login },
Details: { screen: DetailsScreen },
}
)
export default createAppContainer(LoginRouter);
but it gives an error. How can I change it? Why is the method working on the registration page but not my login page?
This is from the App.tsx file:
onst App: React.FC<AppProps> = () => {
// Disable mapbox telemetry due to privacy policy
useEffect(() => {
MapboxGL.setTelemetryEnabled(false);
});
return (
<NavigationNativeContainer>
<NavigationStack.Navigator initialRouteName="Home">
<NavigationStack.Screen
name="Home"
component={HomeScreen}
options={{ headerShown: false }}
/>
<NavigationStack.Screen
name="Registration"
component={RegistrationScreen}
options={{ headerShown: false }}
/>
{/* <NavigationStack.Screen
name="Login"
component={LoginScreen}
options={{ headerShown: false }}
/> */}
<NavigationStack.Screen name="Details" component={DetailsScreen} />
</NavigationStack.Navigator>
</NavigationNativeContainer>
);
};
I get an error that "Login" is not found when I uncomment that section.

Related

React Native - How do I direct to Main Stack screen without logging in and redirect back to Auth Stack from Main Stack screen?

I'm building an app that consists of public and private route.
The private route is as below:
Sign in (starting screen) --> (user signed in) --> Main Stack Screens (Home, Country, Communities, etc.)
The public route is as below:
Sign in (starting screen) --> (user not signed in) --> Main Stack Screens (Home, Country, Communities, etc.) with limited functions and content display to the user
In public route, I'm trying to add a login icon in the header of the Main Stack Screens, so users can be redirected back to the Auth flow and log in or sign up at any point of time when they wish to.
Here is my code for AuthStackNavigator.js:
import React from "react";
import { createStackNavigator } from "#react-navigation/stack";
import SignInScreen from "../screen/authentication/SignInScreen";
import SignUpScreen from "../screen/authentication/SignUpScreen";
import SignUpSuccessScreen from "../screen/authentication/SignUpSuccessScreen";
import PasswordResetScreen from "../screen/authentication/PasswordResetScreen";
const Stack = createStackNavigator();
const AuthStackNavigator = () => {
return (
<Stack.Navigator
initialRouteName="Sign In"
screenOptions={{ headerShown: false }}
>
<Stack.Screen name="Sign In" component={SignInScreen} />
<Stack.Screen name="Sign Up" component={SignUpScreen} />
<Stack.Screen name="Sign Up Success" component={SignUpSuccessScreen} />
<Stack.Screen name="Password Reset" component={PasswordResetScreen} />}
</Stack.Navigator>
);
};
export default AuthStackNavigator;
Here for MainNavigator.js:
import React, { useContext } from "react";
import { Platform, StyleSheet } from "react-native";
import { createStackNavigator } from "#react-navigation/stack";
import CountryScreen from "../screen/CountryScreen";
import CommunitiesScreen from "../screen/CommunitiesScreen";
import CommunityCreateScreen from "../screen/authorized/CommunityCreateScreen";
import CommunityHomeScreen from "../screen/CommunityHomeScreen";
import PostCreateScreen from "../screen/authorized/PostCreateScreen";
import CommentPostScreen from "../screen/authorized/CommentPostScreen";
import SearchBar from "../component/SearchBar";
import { generalconfig } from "../helper/generalconfig";
import { stylesconfig } from "../helper/stylesconfig";
import { AuthContext } from "../src/context/AuthContext";
import CustomProfileImg from "../component/CustomProfileImg";
import DefaultProfileIcon from "../component/DefaultProfileIcon";
import { Entypo } from "react-native-vector-icons";
import LoginIcon from "../component/LoginIcon";
const MainNavigator = () => {
const Stack = createStackNavigator();
const platform = Platform.OS;
const { width } = generalconfig.device;
const headerImageContainer = stylesconfig.global.headerImageContainer;
const { common, ios, aos } = stylesconfig.navigatorHeader;
const { profileImg, token } = useContext(AuthContext);
return (
<Stack.Navigator>
<Stack.Screen
name="Search Country"
component={CountryScreen}
options={{
title: "Search",
headerStyle: {
backgroundColor: common.backgroundColor,
},
headerTitleAlign: "left",
headerTintColor: common.color,
headerTitleStyle: {
fontFamily: platform === "ios" ? ios.fontFamily : aos.fontFamily,
fontWeight: platform === "ios" ? ios.fontWeight : aos.fontWeight,
fontSize: platform === "ios" ? ios.fontSize : aos.fontSize,
},
headerRight: () =>
profileImg ? (
<CustomProfileImg
activeOpacity={1.0}
onPress={() => {}}
src={{ uri: profileImg }}
style={headerImageContainer}
/>
) : (
<DefaultProfileIcon
activeOpacity={1.0}
onPress={() => {}}
iconSize={55}
iconPosition={{ height: 65, marginRight: 11 }}
/>
),
}}
/>
<Stack.Screen
name="Communities"
component={CommunitiesScreen}
options={{
headerStyle: {
backgroundColor: common.backgroundColor,
},
headerTintColor: common.color,
headerTitleStyle: {
fontFamily: platform === "ios" ? ios.fontFamily : aos.fontFamily,
fontWeight: platform === "ios" ? ios.fontWeight : aos.fontWeight,
fontSize: platform === "ios" ? ios.fontSize : aos.fontSize,
},
headerBackTitle: " ",
headerBackImage: () => (
<Entypo
name="controller-fast-backward"
size={23}
style={{ marginLeft: width - 376 }}
color={common.color}
/>
),
headerRight: () => (token ? <LoginIcon /> : null),
}}
/>
<Stack.Screen
name="Create Community"
component={CommunityCreateScreen}
options={{
headerTitle: "Create a Community",
}}
/>
<Stack.Screen name="Community Home" component={CommunityHomeScreen} />
<Stack.Screen name="Create Post" component={PostCreateScreen} />
<Stack.Screen name="Comment Post" component={CommentPostScreen} />
</Stack.Navigator>
);
};
const styles = StyleSheet.create({});
export default MainNavigator;
LoginIcon.js (component)
import React from "react";
import { TouchableOpacity } from "react-native";
import { stylesconfig } from "../helper/stylesconfig";
import { MaterialCommunityIcons } from "react-native-vector-icons";
import AuthStackNavigator from "../navigator/AuthStackNavigator";
const LoginIcon = () => {
const { common } = stylesconfig.navigatorHeader;
return (
<TouchableOpacity
onPress={() => {
<NavigationContainer>
<AuthStackNavigator />
</NavigationContainer>;
}}
>
<MaterialCommunityIcons
name="login"
size={23}
color={common.color}
style={{ marginRight: 15 }}
/>
</TouchableOpacity>
);
};
export default LoginIcon;
SignInScreen.js (partial code of the link navigating to Country Screen when it's pressed)
<CustomButtonLink
custBtnLinkName={browseAroundLabel}
style={[styles.spacing_Browse, styles.align]}
onNavigate={() => {
navigation.navigate(MainNavigator, { screen: "Search Country" });
}}
onNavigate={() => <MainNavigator />}
/>
CustomButtonLink.js (component)
const CustomButtonLink = ({ custBtnLinkName, style, onNavigate }) => {
return (
<TouchableOpacity style={style} onPress={onNavigate}>
<Text
style={[
stylesconfig.global.gtext,
generalconfig.platform.os === "ios"
? stylesconfig.ios.text
: stylesconfig.aos.text,
]}
>
{custBtnLinkName}
</Text>
</TouchableOpacity>
);
};
So my questions are:
How do I direct the user to the public route (Country Screen) if user is not authenticated?
Once user is directed to the public route (say Country Screen), how do I redirect him back to the AuthStackNavigator (Sign In screen) when he clicks the login icon?
I'm quite new to React Native so deeply appreciate it if anyone can help. Thanks!
For Authentication Flows you should be using conditional operations such as "&&", the ternary operator, etc.
The Way recommended by react navigation is to use the above, you can follow their guide here.
E.G.
isSignedIn ? (
<>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
<Stack.Screen name="Settings" component={SettingsScreen} />
</>
) : (
<>
<Stack.Screen name="SignIn" component={SignInScreen} />
<Stack.Screen name="SignUp" component={SignUpScreen} />
</>
)
Apart from #Abhishek Sah answer, it's recommended to detect user authentication state and navigator rerender accordingly. This will help when user successfully registered or logged out.
// Custom hook to continuously listen to user authentication state
const isSignedIn = useAth()
// listen to authentication state and rerender navigation accordingly
useEffect(()=>{
},[isSignedIn])
isSignedIn ? (
<>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
<Stack.Screen name="Settings" component={SettingsScreen} />
</>
) : (
<>
<Stack.Screen name="SignIn" component={SignInScreen} />
<Stack.Screen name="SignUp" component={SignUpScreen} />
</>
)

Using createStackNavigator from #react-navigation/stack, unable to render a stackscreen

Im using createStackNavigator from #react-navigation/stack and I'm trying to render a form page with Formik as one of my stackScreens, but it won't display the page. I'm getting no errors and I believe I have styled it correctly so I'm not sure how to proceed. The home page works so I know the methodology works.
StackNavigator.js
import * as React from 'react';
import { createStackNavigator } from '#react-navigation/stack';
import LinkScreen from "../screens/LinksScreen"
import HomeScreen from "../screens/HomeScreen"
import User from "../screens/User"
import Form from "../screens/Form"
import Info from "../screens/Info"
const Stack = createStackNavigator();
const HomeStackNavigator = () => {
return (
<Stack.Navigator>
<Stack.Screen name ="Home" component={HomeScreen} />
</Stack.Navigator>
)
}
// Settings page
const SettingStackNavigator = () => {
return (
<Stack.Navigator initialRouteName={'Settings'} >
<Stack.Screen name="Settings" component={LinkScreen} />
<Stack.Screen name="Profile" component={User} />
</Stack.Navigator>
);
}
// Form Page
const FormStackNavigator = () => {
return (
<Stack.Navigator>
<Stack.Screen name="Form" component={Form} />
</Stack.Navigator>
);
}
// Other page?
const InfoStackNavigator = () => {
return (
<Stack.Navigator>
<Stack.Screen name="Info" component={Info} />
</Stack.Navigator>
);
}
export { HomeStackNavigator, SettingStackNavigator, FormStackNavigator, InfoStackNavigator };
Form.js
import * as WebBrowser from 'expo-web-browser';
import * as React from 'react';
import { Button, Image, Platform, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import { ScrollView, TextInput } from 'react-native-gesture-handler';
import styles from'./screenStyles'
import {Formik} from 'formik'
export default function Form(){
return(
<View style={styles.container}>
<Formik
initialValues={{Test1: '', Test2: '', Test3:''}}
onSubmit={(values)=>{
console.log(values);
}}
>
{(props)=>{
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder='Test1 Text'
onChangeText={props.handleChange('Test1')}
value={props.values.Test1}
/>
<TextInput
style={styles.input}
placeholder='Test2 Text'
onChangeText={props.handleChange('Test2')}
value={props.values.Test2}
/>
<TextInput
style={styles.input}
placeholder='Test3 Input'
onChangeText={props.handleChange('Test3')}
value={props.values.Test3}
/>
<Button title='Submit' color='blue' onPress={props.handleSubmit}/>
</View>
}}
</Formik>
</View>
);
}
The form page just comes up with the form header but no content.
As looking on to your provided snack you were passing formik properties in the right way but not returning that form so returning that form works.
here is the working code.
export default function Form(){
return(
<View style={styles.container}>
<Formik
initialValues={{Test1: '', Test2: '', Test3:''}}
onSubmit={(values)=>{
console.log(values);
}}
>
{formikProps => ( // here you need to return your form
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder='Test1 Text'
onChangeText={formikProps.handleChange('Test1')}
value={formikProps.values.Test1}
/>
<TextInput
style={styles.input}
placeholder='Test2 Text'
onChangeText={formikProps.handleChange('Test2')}
value={formikProps.values.Test2}
/>
<TextInput
style={styles.input}
placeholder='Test3 Input'
onChangeText={formikProps.handleChange('Test3')}
value={formikProps.values.Test3}
/>
<Button title='Submit' color='blue' onPress={formikProps.handleSubmit}/>
</View>
)}
</Formik>
</View>
);
}
Here is a link to working snack

In React Native Navigation, how do I send props to my screens?

I want to be able to use navigation on a different screen other than just the first one but I am getting an error that this.props does not exist.
I have my App.js file setup like this:
import { createStackNavigator } from '#react-navigation/stack';
import { NavigationContainer } from '#react-navigation/native';
import Screen2 from './screens/Screen2';
import Screen3 from './screens/Screen3';
import HomeScreen from './screens/HomeScreen';
const Stack = createStackNavigator();
function HomeScreen({ navigation }) {
return (
<View>
<Button
title="Go to Screen2"
onPress={() => {
navigation.navigate('Screen2');
}}
/>
<Button
title="Go to Screen3"
onPress={() => {
navigation.navigate('Screen3');
}}
/>
</View>
);
const App: () => React$Node = () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Screen2" component={Screen2} />
<Stack.Screen name="Screen3" component={Screen3} />
</Stack.Navigator>
</NavigationContainer>
);
};
The buttons in app.js work but if I go to Screen2 and click a button that intends to go to another (Screen3 in the example below), props does not exist.
Example Screen2.js would look like this:
const Screen2: () => React$Node = () => {
return (
<>
<View style={{ flex: 1 }}>
<Button
title="Go to Screen3"
onPress={goToScreen3}}
/>
</View>
</>
);
function goToScreen3() {
if(condition){
this.props.navigate.navigate('Screen3');
}}
How do I pass the props so that I can use navigation in my second screen?
For functional component sometimes it's tricky to pass navigation through props as well. So just use withNavigation.
you have to import it and wrap the function with it.
import { withNavigation } from 'react-navigation';
const Screen2 = props => {
const goToScreen3 = () => {
if(condition){
props.navigate.navigate('Screen3');
}}
return (
<>
<View style={{ flex: 1 }}>
<Button
title="Go to Screen3"
onPress={goToScreen3()}
/>
</View>
</>
);
export default withNavigation(Screen2)
In Functional Component there is no this binding so you need to get the props from the function first
check th
const Screen2 = (props) => {
return (
<>
<View style={{ flex: 1 }}>
<Button
title="Go to Screen3"
onPress={goToScreen3}}
/>
</View>
</>
);
function goToScreen3() {
if(condition){
props.navigate.navigate('Screen3');
}
}
}

React native navigation in flatlist

I using the flatlist to display a list of data. I wish to pass the data into another pages, but i have no idea which kind of navigation I shd use.
import Routes from './src/Routes';
export default class App extends Component<Props> {
render() {
return (
<View style={styles.container}>
<StatusBar
backgroundColor="#1c313a"
arStyle="light-content"
/>
<Routes/>
</View>
);
}
}
import React, { Component } from 'react';
import {StyleSheet, View, StatusBar,Text} from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import HomeScreen from '../pages/HomeScreen'
import YourActivitiesScreen from '../pages/YourActivitiesScreen'
import YourFavouriteScreen from '../pages/YourFavouriteScreen'
const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen
name="Home"
component={HomeScreen}
options={{ drawerLabel: 'Home' }}
/>
<Drawer.Screen
name="Your Activities"
component={YourActivitiesScreen}
options={{ drawerLabel: 'Your Activities' }}
/>
<Drawer.Screen
name="Your Favourite"
component={YourFavouriteScreen}
options={{ drawerLabel: 'Your Favourite' }}
/>
</Drawer.Navigator>
);
}
export default function SideMenu() {
return (
<NavigationContainer>
<MyDrawer />
</NavigationContainer>
);
}
import React, { Component } from 'react';
import {Router, Stack, Scene} from 'react-native-router-flux';
import Login from './pages/Login';
import Signup from './pages/Signup';
import SideMenu from './components/SideMenu'
export default class Routes extends Component {
render() {
return(
<Router>
<Stack key="root" hideNavBar>
<Scene key="login" component={Login} title="Login" initial/>
<Scene key="signup" component={Signup} title="Signup" />
<Scene key="home" component={SideMenu} title="HomeScreen" />
</Stack>
</Router>
);
}
}
import React, { Component } from 'react';
import {
StyleSheet,
View,
Text,
AsyncStorage,
TouchableOpacity,
FlatList,
Button,
} from 'react-native';
import DetailsScreen from './Details';
import { createDrawerNavigator, SafeAreaView } from 'react-navigation';
class HomeScreen extends Component{
constructor(props) {
super(props);
this.state = {
activitiesList: [],
}
};
renderItem = (item) => {
return (
<TouchableOpacity
onPress={() => {
console.log('test')
}}
>
<View style={styles.item}>
<Text style={styles.title}>{item.name}</Text>
</View>
</TouchableOpacity>
);
}
render(){
const listActivities = this.state.activitiesList
return (
<View>
<View style={styles.container}>
<Text style={styles.heading}>UPCOMING ACTIVITIES</Text>
</View>
<View>
<SafeAreaView>
<FlatList
data = {listActivities}
renderItem={({ item }) => this.renderItem(item)}
keyExtractor={item => item.id}
/>
</SafeAreaView>
</View>
</View>
)
}
}
I used the react-native-router-flux at the early part of system, which is login, signup and home. Now home display the flatlist, from the flatlist i have to make a onPress to navigate to another pages, the Actions in router-flux that i used before cannot work. Anyone have idea about it? or another better way navigate to to the details of flatlist?
First off, I'd refactor all the code to use just one kind of navigator (in this case, going for react-navigation). So, we will have your router-flux code combined with your
//Your routes screen
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
//... add missing imports
const Stack = createStackNavigator();
//this will be your old router-flux
const Root = () => {
return (
<Stack.Navigator>
<Stack.Screen name="login" component={Login} title="Login" initial/>
<Stack.Screen name="signup" component={Signup} title="Signup" />
<Stack.Screen name="home" component={SideMenu} title="HomeScreen" />
</Stack.Navigator>
)
}
const Drawer = () => {
return (
<Drawer.Screen
name="Home"
component={HomeScreen}
options={{ drawerLabel: 'Home' }}
/>
<Drawer.Screen
name="Your Activities"
component={YourActivitiesScreen}
options={{ drawerLabel: 'Your Activities' }}
/>
<Drawer.Screen
name="Your Favourite"
component={YourFavouriteScreen}
options={{ drawerLabel: 'Your Favourite' }}
/>
</Drawer.Navigator>
)
}
const AppContainer = () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Root" component={Root} />
<Stack.Screen name="Drawer" component={Drawer} />
//import your Details screen to use inside component
<Stack.Screen name="Details" component={Details} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default AppContainer
You will wrap your App.js component with this AppContainer. What we just did was to nest the navigations, your Home will be reached first and your drawer will be all in the same. Also, there is one missing stack in your code that is the one for the Details.
Right after here you are going to use all the actions from react-navigation. All the screens will receive a navigation props. Once you want to navigate from your Root, you will call the navigation just like props.navigation.navigate("Home").
The same will apply to navigate to your Detail screen from the FlatList.
//Your Home Screen
import React, { Component } from 'react';
import {
StyleSheet,
View,
Text,
AsyncStorage,
TouchableOpacity,
FlatList,
Button,
SafeAreaView
} from 'react-native';
class HomeScreen extends Component{
constructor(props) {
super(props);
this.state = {
activitiesList: [],
}
};
renderItem = (item) => {
return (
<TouchableOpacity
onPress={() => {
props.navigation.navigate("Details", { data: item })
console.log('test')
}}
>
<View style={styles.item}>
<Text style={styles.title}>{item.name}</Text>
</View>
</TouchableOpacity>
);
}
render(){
const listActivities = this.state.activitiesList
return (
<View>
<View style={styles.container}>
<Text style={styles.heading}>UPCOMING ACTIVITIES</Text>
</View>
<View>
<SafeAreaView>
<FlatList
data = {listActivities}
renderItem={({ item }) => this.renderItem(item)}
keyExtractor={item => item.id}
/>
</SafeAreaView>
</View>
</View>
)
}
}
Just added the navigation action to the code above. You have to access the params object in your Details Screen
//Details Screen
class DetailsScreen extends React.Component {
render() {
const { routes } = this.props;
return (
<View>
//Your component
<Text>{routes.data.name}</Text>
</View>
);
}
}
Just a side note. If you have a problem when navigating to a nested stack you can navigate this way using params
navigation.navigate(<YourParent>, {
screen: <YourDesiredScreen>,
params: { <YourObject> },
});
I hope it helps, at least as a guide. I didn't tested it, that's why I asked you to upload your code to expo.
I use react-navigation and couldn't be happier. All the navigation needed can be done with a simple:
this.props.navigation.navigate('ScreenName', {param1: 'Hello', param2: 'World'})
and then, when on the screen desired, get the param:
const { param1, param2 } = this.props.route.params;
More details here.
And, of course, if using function components it is even easier.
This example is form my 1st react-native-expo project but I hope that it will help you.
Bottom code is for two stack screens where I have PlayersTab screen and Player so main focus is to access Player with parms from PlayersTab using react-navigation
Navigation is in props object all you need is to destructor it in component const PlayersList = ({ navigation }) => {//your code}
import { View, Text } from 'react-native';
import React from 'react';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import PlayersList from '../personal_data_screen/PlayersList';
import PersonalDataScreenPlayer from'../personal_data_screen/PersonalDataScreenPlayer';
const Stack = createNativeStackNavigator();
const PersonalPlayerDataNavigator = ({ loginDataObject }) => {
return (
<Stack.Navigator>
<Stack.Screen options={{ headerShown: false }} name='PlayersTab'>
{(props) => (
<PlayersList {...props} loginDataObject={loginDataObject} />
)}
</Stack.Screen>
<Stack.Screen options={{ headerShown: false }} name='Player'>
{(props) => <PersonalDataScreenPlayer {...props} />}
</Stack.Screen>
</Stack.Navigator>
);
};
export default PersonalPlayerDataNavigator;
FlatList witch is in PlayersTab looks like this
<FlatList
data={Object.keys(friendList.data)}
renderItem={renderItem}
keyExtractor={keyExtractor}
navigation={navigation}
/>
const renderItem = ({ item }) => (
<Item
navigation={navigation}
account_id={friendList.data[item].account_id}
nickname={friendList.data[item].nickname}
/>
const Item = ({ nickname, account_id, navigation }) => (
<TouchableOpacity
onPress={() => navigation.navigate('Player', { account_id: account_id })}>
<View style={styles.itemView}>
<Text style={styles.playerNicknameText}>{nickname}</Text>
</View>
</TouchableOpacity>
And code for Player screen
import React from 'react';
import { View, Text } from 'react-native';
const PersonalDataScreenPlayer = ({ route }) => {
return (
<View
style={{
flex: 1,
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
}}>
<Text>{route.params.account_id}</Text>
</View>
);
};
export default PersonalDataScreenPlayer;

onPress and onChangeText doing nothing in React Native

My onPress & onChangeText functions doing nothing. If I entered the value, I got this error message
_this.setState is not a function. (In '_this.setState({
username: username
})', '_this.setState' is undefined)
app/index.js
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
username: "",
password: ""
};
this._handlePress = this._handlePress.bind(this)
}
_handlePress = () => {
const { username } = this.state;
const { password } = this.state;
Alert.alert(username);
Alert.alert(password);
onSignIn().then(() => navigation.navigate("SignedIn")); //also not working
}
/**/
render() {
/**/
}
}
app/screens/SignIn.js
import React from "react";
export default ({navigation, _handlePress}) => (
<View style={{ paddingVertical: 20 }}>
<Card title="SIGN IN">
<FormLabel>Email</FormLabel>
<FormInput
placeholder="Email address..."
onChangeText={username => this.setState({username})}
/>
<FormLabel>Password</FormLabel>
<FormInput
secureTextEntry
placeholder="Password..."
onChangeText={password => this.setState({password})}
/>
<Button
buttonStyle={{ marginTop: 20 }}
backgroundColor="#03A9F4"
title="SIGN IN"
onPress={this._handlePress}
/>
</Card>
</View>
);
Reference: https://github.com/datomnurdin/auth-reactnative
you are getting this error as SignIn.js js is just a function and not a Component class. so the function's 'this' does not have any method 'setstate'. You need to write the component within a react class like this
class Signin extends React.Component{
<View style={{ paddingVertical: 20 }}>
<Card title="SIGN IN">
<FormLabel>Email</FormLabel>
<FormInput
placeholder="Email address..."
onChangeText={username => this.setState({username})}
/>
<FormLabel>Password</FormLabel>
<FormInput
secureTextEntry
placeholder="Password..."
onChangeText={password => this.setState({password})}
/>
<Button
buttonStyle={{ marginTop: 20 }}
backgroundColor="#03A9F4"
title="SIGN IN"
onPress={this._handlePress}
/>
</Card>
</View>
}
// i have cloned your repo and run it successfully, by moving username
// and password from index.js to SignIn.js, rewrite SignIn in class way,
// navigation works well(jump to signed successfuly after pressing).
// however not sure if this is what you need.
import React, {Component} from "react";
import { View, Alert } from "react-native";
import { Card, Button, FormLabel, FormInput } from "react-native-elements";
export default class SignIn extends Component {
constructor (props) {
super(props);
this.state = {
username: '',
password: ''
}
}
_handlePress () {
let {navigation} = this.props;
navigation.navigate("SignedIn")
}
_handleUChange (username) {
this.setState({username})
}
_handlePChange (password) {
this.setState({password})
}
render () {
return (
<View style={{ paddingVertical: 20 }}>
<Card title="SIGN IN">
<FormLabel>Email</FormLabel>
<FormInput
placeholder="Email address..."
onChangeText={this._handleUChange.bind(this)}
/>
<FormLabel>Password</FormLabel>
<FormInput
secureTextEntry
placeholder="Password..."
onChangeText={this._handlePChange.bind(this)}
/>
<Button
buttonStyle={{ marginTop: 20 }}
backgroundColor="#03A9F4"
title="SIGN IN"
onPress={this._handlePress.bind(this)}
/>
</Card>
</View>
)
}
}

Categories