I've integrated react hooks form in my react native app and I'm trying to connect the text input with the hooks controller for validation but when I write the username and click on the button it's showing username undefined not sure where the binding gone wrong please check and suggest what should I fix here?
import React, {useState} from 'react'
import { View, Text, Image, StyleSheet, useWindowDimensions, ScrollView, Alert, TextInput } from 'react-native'
import Logo from '../../../assets/images/logo-main.png'
import CustomButton from '../../components/CustomButton/CustomButton';
import CustomInput from '../../components/CustomInput/CustomInput';
import { useNavigation } from '@react-navigation/native';
import {useForm, Controller} from 'react-hook-form';
import { Auth } from 'aws-amplify';
const LoginScreen = () => {
const [loading, setLoading] = useState(false);
const {height} = useWindowDimensions();
const {control, handleSubmit} = useForm();
const navigation = useNavigation();
const onLoginPressed = (data) => {
console.log(data)
// if (loading) {
// return;
// }
// setLoading(true);
// try {
// response = await Auth.signIn(data.username, data.password);
// console.log(response);
// } catch(e) {
// Alert.alert('Opps', e.message);
// }
// setLoading(false);
};
const onForgotPasswordPressed = () => {
navigation.navigate('ForgotPassword');
}
const onRegisterPressed = () => {
navigation.navigate('Register')
}
return (
<ScrollView contentContainerStyle={{ flexGrow: 1, justifyContent: 'center' }} showsVerticalScrollIndicator={false}>
<View style={styles.root}>
<Image source={Logo} style={[styles.logo, {height : height * 0.2}]} resizeMode={'contain'} />
{/* <CustomInput placeholder='Username' />
<CustomInput placeholder='Password' secureTextEntry={true}/> */}
<Controller control={control} name="username" render={({field: value, onChange, onBlur}) =>
<TextInput value={value} onChangeText={onChange} onBlur={onBlur} placeholder='Username' /> } />
<TextInput placeholder='Password'/>
<CustomButton text={loading ? 'Loading...' : 'Login Account'} onPress={handleSubmit(onLoginPressed)} />
<CustomButton text='Forgot Password?' onPress={onForgotPasswordPressed} type='TERTIARY' />
<CustomButton text="Don't have an account? Create one" onPress={onRegisterPressed} type='TERTIARY' />
</View>
</ScrollView>
);
};
const styles = StyleSheet.create({
root: {
alignItems: 'center',
padding: 20,
},
logo: {
width: 200,
maxWidth: 300,
maxHeight: 300,
},
});
export default LoginScreen;
CodePudding user response:
As the react-hook-form
approach, you should import the controller
from useForm
, and then in the controller
, you can render a TextInput
. Also, in the controller's render
attribute, you can use onChange,onBlur
and validate your inputs .
import { useForm, Controller } from "react-hook-form";
...
const LoginScreen = () => {
...
const { control, handleSubmit, formState: { errors } } = useForm({
defaultValues: {
username: '',
}
});
...
const onSubmit = data => console.log(data);
return (
<ScrollView contentContainerStyle={{ flexGrow: 1, justifyContent: 'center' }} showsVerticalScrollIndicator={false}>
...
<Controller
control={control}
rules={{
required: true,
}}
render={({ field: { onChange, onBlur, value } }) => (
<TextInput
style={styles.input}
onBlur={onBlur}
onChangeText={onChange}
value={value}
placeholder='Username'
/>
)}
name="username"
/>
...
</ScrollView>
)
}