React Native添加react-native-form-validator触发Invalid hook call报错
报错原因
你触发Invalid hook call报错的核心原因是违反了React Hook的使用规则:Hook只能在函数组件的顶层作用域内部调用。你把useState、useValidation两个Hook都定义在了Register函数组件的外部,组件加载时这些外部的Hook会先执行,自然就触发了规则校验报错。这也刚好对应你移除Register组件就恢复正常的现象:移除组件后这些外部Hook不会被执行,自然不会报错。
除此之外你的代码还有三处小问题:
useValidation的state参数中引用了未定义的number变量fieldError函数定义时接收的是对象解构参数,但实际调用时传入的是字符串,会导致取值异常fieldError函数没有显式返回值,校验错误提示不会渲染到页面上
解决方案
把所有Hook、依赖Hook返回值的业务逻辑都移到Register组件内部的顶层作用域,同时修正上述三处小问题即可。修正后的完整Register组件代码如下:
import React, {useState} from 'react'; import {StyleSheet, View, Text} from 'react-native'; import AppBtn from '../../components/AppButton'; import CustomText from '../../components/CustomText'; import AppScreen from '../../components/AppScreen'; import TextField from '../../components/TextField'; import Colors from '../../config/Colors'; import {useValidation} from 'react-native-form-validator'; function Register({navigation}) { // 所有Hook移到组件内部顶层 const [name, setName] = useState('Enter Name'); const [email, setEmail] = useState('Enter Mail'); const [newPassword, setNewPassword] = useState('Enter password'); const [confirmPassword, setConfirmPassword] = useState('Confirm password'); const {validate, isFieldInError, getErrorsInField, getErrorMessages} = useValidation({ // 移除不存在的number变量 state: {name, email, newPassword, confirmPassword}, }); // 调整fieldError参数定义,新增返回值 const fieldError = (field) => { if (isFieldInError(field)) { return getErrorsInField(field).map(errorMessage => ( <Text style={styles.text} key={errorMessage}>{errorMessage}</Text> )); } return null; }; const onPressButton = () => { validate({ name: {minlength: 3, maxlength: 30, required: true}, email: {email: true}, newPassword: {minlength: 6, required: true}, confirmPassword: {equalPassword: newPassword}, }); }; return ( <AppScreen style={{alignItems: 'center'}}> <CustomText text="Sign Up" style="bold head" otherStyle={{marginTop: 100}} /> <View style={styles.hairline} /> <TextField data="user name" other="name" onChangeText={setName} value={name} /> {fieldError('name')} <TextField data="mail" onChangeText={setEmail} value={email} /> {fieldError('email')} <TextField data="password" onChangeText={setNewPassword} value={newPassword} /> {fieldError('newPassword')} <TextField data="confirm password" onChangeText={setConfirmPassword} value={confirmPassword} /> {fieldError('confirmPassword')} <AppBtn text="Register" onPress={onPressButton} /> <AppBtn text="Return back" style={{ backgroundColor: Colors.primary, width: '30%', marginTop: 100, }} onPress={() => navigation.navigate('PreAuth')} /> <Text>{getErrorMessages()}</Text> </AppScreen> ); } const styles = StyleSheet.create({ container: {}, hairline: { backgroundColor: Colors.secondary, marginTop: 10, height: 2, width: '50%', marginBottom: 70, }, text: { margin: 10, }, }); export default Register;
修改完成后重新运行项目即可解决报错。
内容的提问来源于stack exchange,提问作者Twfyq Bhyry
相关产品推荐
相关产品推荐

