0

我创建了一个自定义函数组件,它具有来自 NetInfo 的事件监听器用于 Internet 连接,它返回一个布尔值和方法名称。我想在每个类组件中调用该方法来检查互联网连接并使用布尔值来检查连接状态。

下面是我的代码。

//function Component
import React, { PureComponent, useEffect, useState } from 'react';
import  NetInfo  from "@react-native-community/netinfo";


export default () => {
const [isInternetReachable, setIsInternetReachable] = useState(false)
const InternetChecker = () => {
    useEffect(() => {
        // Subscribe
        const unsubscribe = NetInfo.addEventListener((state) => {
            setIsInternetReachable(state.isInternetReachable);
            console.log("Connection type", state.type);
            console.log("Is internet Reachable?", isInternetReachable);
        });
        return () => {
            unsubscribe();
        };
    },[])
}

return [InternetChecker, isInternetReachable];

};

类组件试图访问 InternetChecker() 方法

class HomeScreen extends React.Component {

 render() {
 const { navigate } = this.props.navigation;
 const [InternetChecker, isInternetReachable] = InternetHanlder();
 // if (!isInternetReachable) {
 //     <NoNetworkSign /> 
 // }
 InternetChecker()
 if (isInternetReachable){
  console.log("Internet is Reachable");
 } else {
  console.log("No Internet Connection");
  
 }
 return (
  <SafeAreaView style={styles.container}>
    <View style={styles.container}>
    </View>
  </SafeAreaView>
 )
 };

当我尝试以上述方式访问时,我得到无效的钩子调用,只能从函数组件的主体内部调用钩子。我们如何从类组件中调用它。

任何帮助表示赞赏。

4

3 回答 3

1

为函数添加名称

import React, { PureComponent, useEffect, useState } from 'react';
import  NetInfo  from "@react-native-community/netinfo";


export default ConnectivityChecker = () => {
const [isInternetReachable, setIsInternetReachable] = useState(false)
const InternetChecker = () => {
    useEffect(() => {
        // Subscribe
        const unsubscribe = NetInfo.addEventListener((state) => {
            setIsInternetReachable(state.isInternetReachable);
            console.log("Connection type", state.type);
            console.log("Is internet Reachable?", isInternetReachable);
        });
        return () => {
            unsubscribe();
        };
    },[])
}

return [InternetChecker, isInternetReachable];

};

你想在哪里使用这个功能,你应该导入它

于 2020-07-08T07:45:50.093 回答
1

首先你应该阅读Hooks 规则,第一条规则是不要在基于类的组件中调用反应挂钩,因此只需将 HomeScreen 组件更新为 FC 组件,然后再试一次,它就会正常工作。

你的自定义钩子应该是这样的:

 export const useInternetStatus = () => {// I make a name to your hook is best in inspection and testing
const [isInternetReachable, setIsInternetReachable] = useState(false)
const InternetChecker = () => {
    useEffect(() => {
        // Subscribe
        const unsubscribe = NetInfo.addEventListener((state) => {
            setIsInternetReachable(state.isInternetReachable);
            console.log("Connection type", state.type);
            console.log("Is internet Reachable?", isInternetReachable);
        });
        return () => {
            unsubscribe();
        };
    },[isInternetReachable]) // in order to re-call the hooks whenever the netInfo status changed 
}

return [InternetChecker, isInternetReachable];

};
于 2020-07-08T07:56:12.833 回答
0

您显示的功能不是功能组件,因为它不会返回可以呈现的内容。你也称它为钩子。您可以做的是首先解决自定义挂钩的问题:

  1. 它返回一个钩子(一个InternetChecker调用的函数useEffect)。那是不需要的。钩子应该只调用它useEffect自己,所以它会NetInfo在挂载时订阅。

  2. unsubscribe顾名思义,该函数应该取消订阅NetInfo. 否则它将导致内存泄漏,因为即使您的组件已经卸载,您的侦听器也会被调用。

const useInternetStatus = () => {
    const [reachable, setReachable] = useState(false);
    
    useEffect(() => {
        const subscribe = state => setReachable(state.isInternetReachable); 

        NetInfo.addEventListener(subscribe);

        return () => NetInfo.removeEventListener(subscribe);
    },[]);

    return reachable;
};

然后你可以将你的组件重写HomeScreen为一个功能组件,它允许你在其中使用钩子:

const HomeScreen = () => {
    const isInternetReachable = useInternetStatus();

    console.log(isInternetReachable);

    return (
        <SafeAreaView style={styles.container}>
            <View style={styles.container}>
            </View>
        </SafeAreaView>
    );
};
于 2020-07-08T08:30:10.833 回答