开发者问题收集

React Native !!! 错误:无效的钩子调用。钩子只能在函数组件的主体内调用

2022-09-21
5497

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

  1. 您的 React 和渲染器版本可能不匹配(例如 React DOM)
  2. 您可能违反了钩子规则
  3. 您可能在同一个应用程序中拥有多个 React 副本
    函数组件主体的主体。这可能是由于以下原因之一而发生的:
  4. 您的 React 和渲染器版本可能不匹配(例如 React DOM)
  5. 您可能违反了钩子规则3。您可能在同一个应用中拥有多个 React 副本。请参阅 https://reactjs.org/link/invalid-hook-call ,了解如何调试和修复此问题的提示。错误 TypeError:null 不是对象(评估“dispatcher.useState”) 错误 Invariant Violation:“main”尚未注册。如果发生以下情况,可能会发生这种情况:* Metro(本地开发服务器)从错误的文件夹运行。检查 Metro 是否正在运行,停止它并在当前项目中重新启动它。
  • 由于错误,模块加载失败,并且未调用 AppRegistry.registerComponent

我的代码

**import * as React from 'react';
import {useState} from 'react';
import { Text, StyleSheet, 
KeyboardAvoidingView, ScrollView, Image,
TextInput, TouchableOpacity, View } from 'react-native';
import { CheckBox } from 'react-native-elements';
import {Ionicons} from '@expo/vector-icons'

const [input, setInput] = useState('');
const [hidePass, setHidePass] = useState(true);
export default class App extends React.Component {
 

    constructor(props) {
      super(props);
      this.state = {
          ischecked1: true
      };
  }
    onChangeCheck1() {
      this.setState({ ischecked1: !this.state.ischecked1 });
    }
    render() {
      
        return (
          
            <KeyboardAvoidingView
            style={styles.container}
             >
            <ScrollView>
              
                <Image
                    source={require('./assets/logo.png')}
                    style={styles.logo}
                    />
                <Text style={styles.helloText}> 
                Olá de novo !
                </Text>
               <Text style={styles.welcomeText}>
                  Bem-vindo(a) de volta,
                  sentimos sua falta! 
                </Text>
               
                <TextInput
                style={styles.inputArea}
                placeholder="Digite o e-mail"
                />
                <TextInput
                style={styles.inputArea}
                placeholder="Senha"
                value={input}
                onChangeText={ (texto) => setInput(texto)}
                secureTextEntry={hidePass}
                />
                <TouchableOpacity style={styles.eye} onPress={ () =>
                   setHidePass(!hidePass) }>
                  <Ionicons name={hidePass ? 'eye' : 'eye-off'}
                   color="#A0D800" size={25}/>
                </TouchableOpacity>
                <View style={styles.checkBoxStyle}>
                <CheckBox
                  left
                  size={18}
                  checkedColor='#A0D800'
                  value={this.state.ischecked1}
                  checked={this.state.ischecked1}
                  onPress={this.onChangeCheck1.bind(this)}
                  containerStyle={{ backgroundColor: "transparent",
                  borderColor: "transparent", marginRight: 0}}
                />
              <Text style={styles.Connected}> 
                Manter-se conectado
              </Text>
                <Text style={styles.forgotPassword}> 
                  Esqueci minha senha
                </Text>
                
                </View>
                
          
                <TouchableOpacity 
                    style={styles.botao}
                    /*onPress={ () => {this.clicou()} }*/
                >
                    <Text style={styles.botaoText}>Entrar</Text>
                </TouchableOpacity>
                
                
            </ScrollView>
            </KeyboardAvoidingView>
            
        );
    }
}
const styles = StyleSheet.create({
    container: {
        flex: 2,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#fff'
    },
    logo: {      
        marginTop:50,
        marginBottom: 80,
        width: 150,
        height: 40,
        
    },
    inputArea:{
       marginTop: 30,
       padding: 15,
       height: 60,
       width: 370,
       borderColor: '#808080',
       borderWidth: 1,
       backgroundColor: '#fff',
       fontSize: 16,
       fontWeight: 'bold',
       borderRadius: 15
    },
    botao: {
        width: 350,
        height: 60,
        backgroundColor: '#000000',
        marginTop: 50,
        marginLeft: 8,
        borderRadius: 15,
        alignItems: 'center',
        justifyContent: 'center'
    },
    botaoText: {
      fontSize: 15,
      fontWeight: 'bold',
      color: '#fff'
    },
    helloText: {
      fontSize: 40,
      fontWeight: 'bold',
      marginTop: 15,
      color: '#000000',
      marginEnd: 120,
      marginTop: 8
    },
    welcomeText: {
      fontSize: 16,
      marginTop: 10,
      marginEnd: 35,
      marginVertical: 10,
      color: '#808080',
    },
    forgotPassword: {
      textDecorationLine: 'underline',
      fontWeight: 'bold',
      marginTop: 15,
      marginBottom: 15,
      marginLeft: 30,
      fontSize: 12
    },
    Connected:{
      textDecorationLine: 'underline',
      fontWeight: 'bold',
      marginTop: 15,
      fontSize: 12,
      marginRight: 55,
      marginLeft: -5
    },
    checkBoxStyle:{
      marginTop: 15,
      flexDirection: 'row',
      marginStart: -10
   },
   eye:{
   alignSelf: 'flex-end',
   bottom: 42,
   right: 40
   }
})**
2个回答

错误非常简单。 您有一个扩展 React.Component 的类,并且在构造函数中定义了一个状态,为什么需要 useState 钩子? 您必须选择其中一个,使用钩子的函数组件或类组件。以 useXXX 开头的函数是钩子,这是一种命名约定。

有关钩子的更多信息,请参见此处: https://reactjs.org/docs/hooks-intro.html

摘自此页面:

钩子是 React 16.8 中的新增功能。它们让你无需编写类即可使用状态和其他 React 功能。

删除类声明上方的 2 行应该可以解决问题。

如果我错了,请大家纠正我,但在我看来,你不能同时使用两者,因为 React 如何跟踪状态,需要对要监视的值进行单一引用。

希望我能帮上忙。

AR7CORE
2022-09-21

您必须在类组件或功能组件之间进行选择。

这里,您有一个类组件,但 useState 只能在功能组件中使用。

我已经将您的组件重写为功能组件,您可以尝试用这个替换所有组件:

import * as React from 'react';
import {useState} from 'react';
import { Text, StyleSheet, 
KeyboardAvoidingView, ScrollView, Image,
TextInput, TouchableOpacity, View } from 'react-native';
import { CheckBox } from 'react-native-elements';
import {Ionicons} from '@expo/vector-icons'

const App = () => {
const [input, setInput] = useState('');
const [hidePass, setHidePass] = useState(true);
const [ischecked1, setIschecked1] = useState(true)

const onChangeCheck1 = () => {
    setIschecked1(!ischecked1)
}
  
return (
    
    <KeyboardAvoidingView
        style={styles.container}
    >
        <ScrollView>
            <Image
                source={require('./assets/logo.png')}
                style={styles.logo}
            />
            <Text style={styles.helloText}> 
                Olá de novo !
            </Text>
            <Text style={styles.welcomeText}>
                Bem-vindo(a) de volta,
                sentimos sua falta! 
            </Text>
            
            <TextInput
                style={styles.inputArea}
                placeholder="Digite o e-mail"
            />
            <TextInput
                style={styles.inputArea}
                placeholder="Senha"
                value={input}
                onChangeText={ (texto) => setInput(texto)}
                secureTextEntry={hidePass}
            />
            <TouchableOpacity style={styles.eye} onPress={ () => setHidePass(!hidePass) }>
                <Ionicons name={hidePass ? 'eye' : 'eye-off'}
                    color="#A0D800" size={25}
                />
            </TouchableOpacity>
            <View style={styles.checkBoxStyle}>
                <CheckBox
                    left
                    size={18}
                    checkedColor='#A0D800'
                    value={ischecked1}
                    checked={ischecked1}
                    containerStyle={{ backgroundColor: "transparent",
                    borderColor: "transparent", marginRight: 0}}
                />
                <Text style={styles.Connected}> 
                    Manter-se conectado
                </Text>
                <Text style={styles.forgotPassword}> 
                    Esqueci minha senha
                </Text>
            </View>
            
            <TouchableOpacity 
                style={styles.botao}
                /*onPress={ () => {this.clicou()} }*/
            >
                <Text style={styles.botaoText}>Entrar</Text>
            </TouchableOpacity>
        </ScrollView>
    </KeyboardAvoidingView>
);

}
const styles = StyleSheet.create({
container: {
    flex: 2,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#fff'
},
logo: {      
    marginTop:50,
    marginBottom: 80,
    width: 150,
    height: 40,
    
},
inputArea:{
   marginTop: 30,
   padding: 15,
   height: 60,
   width: 370,
   borderColor: '#808080',
   borderWidth: 1,
   backgroundColor: '#fff',
   fontSize: 16,
   fontWeight: 'bold',
   borderRadius: 15
},
botao: {
    width: 350,
    height: 60,
    backgroundColor: '#000000',
    marginTop: 50,
    marginLeft: 8,
    borderRadius: 15,
    alignItems: 'center',
    justifyContent: 'center'
},
botaoText: {
  fontSize: 15,
  fontWeight: 'bold',
  color: '#fff'
},
helloText: {
  fontSize: 40,
  fontWeight: 'bold',
  marginTop: 15,
  color: '#000000',
  marginEnd: 120,
  marginTop: 8
},
welcomeText: {
  fontSize: 16,
  marginTop: 10,
  marginEnd: 35,
  marginVertical: 10,
  color: '#808080',
},
forgotPassword: {
  textDecorationLine: 'underline',
  fontWeight: 'bold',
  marginTop: 15,
  marginBottom: 15,
  marginLeft: 30,
  fontSize: 12
},
Connected:{
  textDecorationLine: 'underline',
  fontWeight: 'bold',
  marginTop: 15,
  fontSize: 12,
  marginRight: 55,
  marginLeft: -5
},
checkBoxStyle:{
  marginTop: 15,
  flexDirection: 'row',
  marginStart: -10
},
eye:{
alignSelf: 'flex-end',
bottom: 42,
right: 40
}
})

export default App
Paul Angot
2022-09-21