You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 12:48:03