无效的钩子调用 React Native

问题描述

我的注册屏幕上不断出现此错误。如果您能告诉我问题是什么,我将不胜感激。谢谢!

错误:无效的挂钩调用。钩子只能在函数组件的主体内部调用。这可能是由于以下原因之一造成的:

  1. 您的 React 和渲染器版本可能不匹配(例如 React DOM)
  2. 你可能违反了钩子规则
  3. 您可能在同一个应用中拥有多个 React 副本 有关如何调试和解决此问题的提示,请参阅 https://fb me/react-invalid-hook-call。
import { imagebackground,StyleSheet,StatusBar,Dimensions,View,Image } from 'react-native';
import { Block,Button,Text,theme } from 'galio-framework';
import * as Yup from 'yup';
import SafeView from '../components/SafeView';
import Form from '../components/Forms/Form';
import FormField from '../components/Forms/FormField';
import FormButton from '../components/Forms/FormButton';
import IconButton from '../components/IconButton';
import FormErrorMessage from '../components/Forms/FormErrorMessage';
import { registerWithEmail } from '../config/firebase';

const { height,width } = Dimensions.get('screen');
const validationSchema = Yup.object().shape({
  name: Yup.string()
    .required()
    .label('Name'),email: Yup.string()
    .required('Please enter a valid email')
    .email()
    .label('Email'),password: Yup.string()
    .required()
    .min(6,'Password must have at least 6 characters')
    .label('Password'),confirmPassword: Yup.string()
    .oneOf([Yup.ref('password')],'Confirm Password must match Password')
    .required('Confirm Password is required')
});
const [passwordVisibility,setPasswordVisibility] = useState(true);
const [rightIcon,setRightIcon] = useState('eye');
const [confirmPasswordIcon,setConfirmPasswordIcon] = useState('eye');
const [confirmPasswordVisibility,setConfirmPasswordVisibility] = useState(true);
const [registerError,setRegisterError] = useState('');

function handlePasswordVisibility() {
  if (rightIcon === 'eye') {
    setRightIcon('eye-off');
    setPasswordVisibility(!passwordVisibility);
  } else if (rightIcon === 'eye-off') {
    setRightIcon('eye');
    setPasswordVisibility(!passwordVisibility);
  }
}

function handleConfirmPasswordVisibility() {
  if (confirmPasswordIcon === 'eye') {
    setConfirmPasswordIcon('eye-off');
    setConfirmPasswordVisibility(!confirmPasswordVisibility);
  } else if (confirmPasswordIcon === 'eye-off') {
    setConfirmPasswordIcon('eye');
    setConfirmPasswordVisibility(!confirmPasswordVisibility);
  }
}

async function handleOnSignUp(values,actions) {
  const { email,password } = values;
  try {
    await registerWithEmail(email,password);
  } catch (error) {
    setRegisterError(error.message);
  }
}

export default class Register extends React.Component {
  render() {
    const { navigation } = this.props;
    return (
      <SafeView style={styles.container}>
        <Form
          initialValues={{
            name: '',email: '',password: '',confirmPassword: ''
          }}
          validationSchema={validationSchema}
          onSubmit={values => handleOnSignUp(values)}
        >
          <FormField
            name="name"
            leftIcon="account"
            placeholder="Enter name"
            autoFocus={true}
          />
          <FormField
            name="email"
            leftIcon="email"
            placeholder="Enter email"
            autoCapitalize="none"
            keyboardType="email-address"
            textContentType="emailAddress"
          />
          <FormField
            name="password"
            leftIcon="lock"
            placeholder="Enter password"
            autoCapitalize="none"
            autoCorrect={false}
            secureTextEntry={passwordVisibility}
            textContentType="password"
            rightIcon={rightIcon}
            handlePasswordVisibility={handlePasswordVisibility}
          />
          <FormField
            name="confirmPassword"
            leftIcon="lock"
            placeholder="Confirm password"
            autoCapitalize="none"
            autoCorrect={false}
            secureTextEntry={confirmPasswordVisibility}
            textContentType="password"
            rightIcon={confirmPasswordIcon}
            handlePasswordVisibility={handleConfirmPasswordVisibility}
          />
          <FormButton title={'Register'} />
          {<FormErrorMessage error={registerError} visible={true} />}
        </Form>
        <IconButton
          style={styles.backButton}
          iconName="keyboard-backspace"
          color={Colors.white}
          size={30}
          onPress={() => navigation.goBack()}
        />
      </SafeView>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    padding: 15,},backButton: {
    justifyContent: 'center',alignItems: 'center',marginVertical: 10
  }
});```

解决方法

您正在混合基于函数和类的组件。 React Hooks 只能在函数式组件中使用。将您的 Register 组件转换为功能组件并将所有 useState 调用移到组件内。

,

正如错误所暗示的那样,您没有正确使用钩子。钩子需要位于功能组件内部。目前,您在没有组件的情况下使用它们。你这里唯一的组件是一个类组件,所以如果你想使用钩子,你需要先把它转换成一个功能组件,像这样:

import React,{ useState } from 'react';

const Register = (props) => {

  const [passwordVisibility,setPasswordVisibility] = useState(true);
  const [rightIcon,setRightIcon] = useState('eye');
  const [confirmPasswordIcon,setConfirmPasswordIcon] = useState('eye');
  const [confirmPasswordVisibility,setConfirmPasswordVisibility] = useState(true);
  const [registerError,setRegisterError] = useState('');

  // other component logic code here

  return (
    // your component rendering code here
  );
}

export default Register;