我有一个注册屏幕,我为它构建了两个 costom hook。
但我无法按预期使用验证方法。 这是注册屏幕
import React, {useState} from 'react';
import {
View,
Text,
StatusBar,
Keyboard,
TouchableOpacity,
ScrollView,
} from 'react-native';
import Icon from 'react-native-vector-icons/AntDesign';
import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
import Input from '../../../components/input';
import Btn from '../../../components/button';
import CheckBox from '../../../components/checkbox';
import PressableText from '../../../components/pressable';
import {styles} from './style';
import useSignup from './customHooks/useSignup';
import useValidation from './customHooks/utils';
const Signup = ({navigation}) => {
const [
id,
setId,
name,
setName,
email,
setEmail,
pass,
setPass,
confirmPass,
setConfirmPass,
validated,
setValidated,
] = useSignup();
const [validation] = useValidation();
return (
<View style={styles.container}>
<StatusBar barStyle="dark-content" />
<TouchableOpacity activeOpacity={1} onPress={() => Keyboard.dismiss()}>
<ScrollView contentContainerStyle={styles.ScrollView}>
<View style={styles.backIconView}>
<Icon
name="arrowleft"
size={40}
color={'#807D89'}
onPress={() => navigation.goBack()}
/>
</View>
<View style={styles.textView}>
<Text style={styles.heading}>Create Account</Text>
<Text style={styles.para}>Please fill input below to continue</Text>
</View>
<KeyboardAwareScrollView
resetScrollToCoords={{x: 0, y: 0}}
contentContainerStyle={styles.loginForm}>
<Input
text="ID"
placeholder="Enter Your ID"
keyboardType="number-pad"
icon="key"
secureTextEntry={false}
value={id}
onChangeText={(e) => setId(e)}
/>
<Input
text="Full Name"
placeholder="Enter Name"
keyboardType="default"
icon="user"
secureTextEntry={false}
value={name}
onChangeText={(e) => {
setName(e);
}}
/>
<Input
text="Email"
placeholder="Enter Email"
keyboardType="email-address"
icon="mail"
secureTextEntry={false}
value={email}
onChangeText={(e) => setEmail(e)}
/>
<Input
text="Password"
placeholder="Enter Password"
keyboardType="default"
icon="lock"
secureTextEntry={true}
value={pass}
onChangeText={(e) => setPass(e)}
/>
<Input
text="Confirm Password"
placeholder="Enter Password"
keyboardType="default"
icon="lock"
secureTextEntry={true}
value={confirmPass}
onChangeText={(e) => setConfirmPass(e)}
/>
<View style={styles.checkboxView}>
<CheckBox />
<View style={{flexDirection: 'row'}}>
<Text style={{...styles.signUpViewText, fontSize: 20}}>
I accept all{' '}
</Text>
<PressableText
text={'Terms and Conditions'}
fontSize={18}
action={() => alert('Terms')}
/>
</View>
</View>
<Btn
text="Sign Up"
action={() => {
validation();
if (validated) {
useSignup();
navigation.navigate('Home');
}
}}
/>
</KeyboardAwareScrollView>
<View style={styles.signUpView}>
<Text style={styles.signUpViewText}>Already have an account? </Text>
<PressableText
text="LogIn"
fontSize={18}
action={() => navigation.navigate('Login')}
/>
</View>
</ScrollView>
</TouchableOpacity>
</View>
);
};
export default Signup;
这里是 useSignup 钩子:
import React, {useState} from 'react';
import auth from '@react-native-firebase/auth';
export default useSignup = () => {
// auth()
// .createUserWithEmailAndPassword(email, pass)
// .then(() => {
// console.log('User account created & signed in!');
// alert(`signed in with ${email}`);
// })
// .catch((error) => {
// if (error.code === 'auth/email-already-in-use') {
// console.log('That email address is already in use!');
// }
// if (error.code === 'auth/invalid-email') {
// console.log('That email address is invalid!');
// }
// console.error(error);
// });
// console.log(email, 'email');
// console.log(pass, 'pass');
const [id, setId] = useState('');
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [pass, setPass] = useState('');
const [confirmPass, setConfirmPass] = useState('');
const [validated, setValidated] = useState(false);
console.log(id, 'in signup');
return [
id,
setId,
name,
setName,
email,
setEmail,
pass,
setPass,
confirmPass,
setConfirmPass,
validated,
setValidated,
];
};
这里是 useValidation 钩子:
import useSignup from './useSignup';
export default useValidation = () => {
const [id, name, email, pass, confirmPass, setValidated] = useSignup();
console.log(id, 'in utils');
const validation = () => {
id == ''
? alert('Enter ID')
: name == '' || email == ''
? alert('User not Found')
: pass == '' || confirmPass == ''
? alert('enter Password')
: pass != confirmPass
? alert('Pass does not match')
: setValidated(true);
};
return [validation];
};
我做错了什么?
答案 0 :(得分:1)
完全不确定您想要完成什么。对我来说,自定义钩子应该是可重用的并且可以描述它们的响应。我认为 useSignup 很好,但 useValidation 对我来说听起来不应该绑定到 useSignup,并且可能用于其他形式以及具有不同元素和验证规则的其他形式。
可以在 https://codesandbox.io/s/musing-vaughan-srw66
找到并测试以下代码如果您想为表单使用自定义钩子,一个想法是使整个表单成为单个钩子。在代码中,我没有使用 useSignup 或 useValidateor 而是使用 useForm 来处理表单元素和事件逻辑。默认值可以作为可选的第三个参数添加到 useForm 或使用 values.email || 在表单元素的 value 属性中添加'test@testson.com'。 我还外包了验证功能,以便 useForm 可以与任何表单和验证方法一起使用,以使其可重用。
useForm.js
const useForm = (validate, onSubmit, initalValues) => {
const [values, setValues] = useState(initalValues ? initalValues : {});
const [errors, setErrors] = useState([]);
const [isSubmitting, setIsSubmitting] = useState(false);
useEffect(() => {
if (Object.keys(errors).length === 0 && isSubmitting) onSubmit();
setIsSubmitting(false);
}, [errors]);
const handleSubmit = (event) => {
event.preventDefault();
setErrors(validate(values));
setIsSubmitting(true);
};
const setValue = (name, value) => {
setValues((values) => ({
...values,
[name]: value
}));
};
return {
setValue,
handleSubmit,
values,
errors
};
};
App.js
const formValidatior = (values) => {
const errors = [];
if (!values || !values.email) errors.push("Email must be specified");
const emailRegex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
if (!emailRegex.test(String(values.email).toLowerCase()))
errors.push("Email not valid");
//Other validation of values
return errors;
};
export default function Form() {
const { values, errors, setValue, handleSubmit } = useForm(
formValidatior,
handleValidationSuccessOnSubmit
//{ email: "test" } //possibility to add initial values or nonform values
);
function handleValidationSuccessOnSubmit() {
console.log("PASSED VALIDATION");
}
return (
<div>
<form onSubmit={handleSubmit}>
<label>Email</label>
<input
type="text"
name="email"
placeholder="Your email..."
onChange={(event) => setValue(event.target.name, event.target.value)}
value={values.email || ""} // "" becomes default value
/>
<input type="submit" value="Submit" />
{errors ? errors.map((error) => <p>{error}</p>) : null}
</form>
</div>
);
}
来自https://upmostly.com/tutorials/form-validation-using-custom-react-hooks的想法