Reactjs useValidation挂钩未按预期工作
我有一个注册屏幕,我为它建立了两个costom挂钩Reactjs useValidation挂钩未按预期工作,reactjs,react-native,react-hooks,Reactjs,React Native,React Hooks,我有一个注册屏幕,我为它建立了两个costom挂钩 useSignup,其中定义了我的注册方法及其局部 util钩子,我在其中定义了验证方法 但我无法按预期使用验证方法。 这是注册屏幕 import React, {useState} from 'react'; import { View, Text, StatusBar, Keyboard, TouchableOpacity, ScrollView, } from 'react-native'; import Icon
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;
下面是useValidation hook:
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];
};
我做错了什么?不完全确定你想要完成什么。对于我来说,定制钩子应该是可重用的,并且描述它们的响应。我想useSignup很好,但是useValidation对我来说听起来似乎不应该与useSignup绑定,并且可能在其他形式中使用不同的元素和验证规则 以下代码可在以下位置找到并测试: 如果您想对表单使用自定义钩子,一个想法是将整个表单变成一个钩子。在代码中,我没有使用useSignup或useValidateor,而是使用useForm,它处理表单元素和事件逻辑。可以将默认值作为可选的第三个参数添加到useForm中,也可以将默认值添加到带有values.email | |'的表单元素中的value prop中test@testson.com'. 我还外包了validate函数,以便useForm可以与任何表单和validate方法一起使用,从而使其可重用
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 | |!values.email)错误.push(“必须指定电子邮件”);
const emailRegex=/^([^()[\]\\,;:\s@“]+(\.[^()[\]\,;:\s@“]+)*)(“+”)(\[[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[1,3}.[0-9]{1,3}.]124;([a-zA Z-0-9]++]2});
if(!emailRegex.test(字符串(values.email.toLowerCase()))
错误。推送(“电子邮件无效”);
//价值的其他验证
返回错误;
};
导出默认函数表单(){
const{values,errors,setValue,handleSubmit}=useForm(
formValidatior,
扶手电梯成功提交
//{email:“test”}//添加初始值或非形式值的可能性
);
函数handleValidationSuccessOnSubmit(){
console.log(“通过验证”);
}
返回(
电子邮件
setValue(event.target.name,event.target.value)}
value={values.email | |“}/”成为默认值
/>
{errors?errors.map((error)=>{error}):null}
);
}
Idea from在注册组件中,您使用useSignup返回许多状态。但是你也有useValidation,这反过来会创建一个新的useSignup。更新注册组件中的状态时,useValidation中的状态不会更新。基本上,您有两种不同的注册状态。
useSignup
返回一个包含12项的数组,useValidation
仅对其中6项进行分解,并且您使用的那些项不对应。建议您使用对象而不是数组。@请更正代码。如果我能看到代码的变化,我很容易理解我的错误。我理解其中一些,但不知道如何解决它,因为这是我第一次与custom交互hooks@WillJenkins钩子不是只对数组有效吗?@aqsaman-Nope,你可以随意返回。
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>
);
}