【问题标题】:I'm already using a functional component and I keep getting error : Hooks can only be called inside the body of a function component我已经在使用功能组件,但我不断收到错误:只能在功能组件的主体内调用挂钩
【发布时间】:2021-09-13 08:58:45
【问题描述】:

您好,我正在尝试在我的组件中使用钩子,但我不断收到此消息: Hooks 只能在函数组件内部调用。

您可能会看到它的三个常见原因:

您的 React 和 React DOM 版本可能不匹配。 您可能违反了 Hooks 规则。 您可能在同一个应用中拥有多个 React 副本。

虽然我的 react 版本是 17.0.2 我的 react dom 版本是 17.0.2 而我的 react native 版本是 0.64.2

这是我的代码

import React,{useState,useEffect} from 'react';
import {View, Text, Alert, StyleSheet, TouchableOpacity} from 'react-native';

import {
  DrawerContentScrollView,
  DrawerItemList,
  DrawerItem,
} from '@react-navigation/drawer';

import AsyncStorage from '@react-native-community/async-storage';
import { GoogleSignin, statusCodes } from '@react-native-google-signin/google-signin';

const CustomSidebarMenu = (props) => {
  const[user,setUser] = useState({})
    
    signOut = async () => {
        try {
          await GoogleSignin.revokeAccess();
          await GoogleSignin.signOut();
          this.setState({ user: null }); // Remember to remove the user from your app's state as well
        } catch (error) {
          console.error(error);
        }
      };

      getCurrentUser = async () => {
        
        const currentUser = await GoogleSignin.getCurrentUser();
        setUser(currentUser)
  
      };

  return (
    <View style={stylesSidebar.sideMenuContainer}>
      <View style={stylesSidebar.profileHeader}>
        <View style={stylesSidebar.profileHeaderPicCircle}>
          <Text style={{fontSize: 25, color: '#307ecc'}}>
            {'A'.charAt(0)}
          </Text>
        </View>
        <Text >
            {user}
        </Text>
      </View>
      <View style={stylesSidebar.profileHeaderLine} />

      <DrawerContentScrollView {...props}>
        <DrawerItemList {...props} />

          
        
        <DrawerItem
          label={({color}) => 
            <Text style={{color: '#d8d8d8'}}>
              Déconnexion
            </Text>
          }
          onPress={() => {
            props.navigation.toggleDrawer();
            Alert.alert(
              'Déconnexion',
              'Vous êtes sur?',
              [
                {
                  text: 'Annuler',
                  onPress: () => {
                    return null;
                  },
                },
                {
                  text: 'Confirmer',
                  onPress: () => {
                    AsyncStorage.clear();
                    props.navigation.replace('Auth');
                    signOut();
                  },
                },
              ],
              {cancelable: false},
            );
          }}
        />
      </DrawerContentScrollView>
    </View>
  );
};

export default CustomSidebarMenu;

const stylesSidebar = StyleSheet.create({
  sideMenuContainer: {
    width: '100%',
    height: '100%',
    backgroundColor: '#307ecc',
    paddingTop: 40,
    color: 'white',
  },
  profileHeader: {
    flexDirection: 'row',
    backgroundColor: '#307ecc',
    padding: 15,
    textAlign: 'center',
  },
  profileHeaderPicCircle: {
    width: 60,
    height: 60,
    borderRadius: 60 / 2,
    color: 'white',
    backgroundColor: '#ffffff',
    textAlign: 'center',
    justifyContent: 'center',
    alignItems: 'center',
  },
  profileHeaderText: {
    color: 'white',
    alignSelf: 'center',
    paddingHorizontal: 10,
    fontWeight: 'bold',
  },
  profileHeaderLine: {
    height: 1,
    marginHorizontal: 20,
    backgroundColor: '#e2e2e2',
    marginTop: 15,
  },
});

【问题讨论】:

  • 这听起来像是你在哪里使用 CustomSidebarMenu(你没有显示)的问题。该错误表明您只是将其作为函数调用,而不是将其用作组件函数。另外,signOut 函数的内容看起来很奇怪:它有一个 this.setState 调用,就好像这是一个类组件。
  • 你的代码也沦为我所说的The Horror of Implicit Globals 的牺牲品:你永远不会声明signOutgetCurrentUser。 (我强烈建议使用严格模式,所以它应该一直是错误的。)
  • 或者只使用函数声明而不是函数表达式。

标签: javascript react-native react-hooks use-effect use-state


【解决方案1】:

我认为这是因为您忘记在 signOut 中将 this.setState 更改为 setUser

   

    const signOut = async () => {
        try {
          await GoogleSignin.revokeAccess();
          await GoogleSignin.signOut();
          setUser(null); // Remember to remove the user from your app's state as well
        } catch (error) {
          console.error(error);
        }
      };

【讨论】:

    【解决方案2】:

    我想你忘记在你的函数中声明const

     const signOut = async () => {
            try {
              await GoogleSignin.revokeAccess();
              await GoogleSignin.signOut();
              this.setState({ user: null }); // Remember to remove the user from your app's state as well
            } catch (error) {
              console.error(error);
            }
          };
    
          const getCurrentUser = async () => {
            
            const currentUser = await GoogleSignin.getCurrentUser();
            setUser(currentUser)
      
          };
    

    async function signOut() {}
    async function getCurrentUser() {}
    

    【讨论】:

    • 这可能是真的,但它不会触发问题所在的错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-15
    • 2021-11-11
    相关资源
    最近更新 更多