无效的 Hook 调用 React Native

Invalid Hook Call React Native

我的注册屏幕上一直出现此错误。如果您能让我知道问题出在哪里,我将不胜感激。谢谢!

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app See https: //fb me/react-invalid-hook-call for tips about how to debug and fix this problem.
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
  }
});```

您正在混合功能组件和基于 class 的组件。 React Hooks 只能在功能组件内部使用。将您的 Register 组件转换为功能组件,并将所有 useState 调用移至组件内。

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

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;