无效的 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:
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- 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;
我的注册屏幕上一直出现此错误。如果您能让我知道问题出在哪里,我将不胜感激。谢谢!
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:
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- 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;