我如何从功能组件到类组件访问可重用的NetInfo代码

时间:2020-07-08 05:14:34

标签: reactjs react-native-ios react-component react-native-community-netinfo

我创建了一个自定义函数组件,该组件具有来自NetInfo的eventlistener,用于Internet连接,该组件将返回bool值和方法名称。我想在每个类组件中调用该方法以检查Internet连接,并使用bool值检查连接状态。

下面是我的代码。

//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>
 )
 };

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

任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:1)

首先,您应该阅读Hooks Rules,第一个规则是不要在基于类的组件内调用react钩子,因此只需将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];

};

答案 1 :(得分:0)

为函数添加名称

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];

};

要使用此功能的位置 您应该导入

答案 2 :(得分: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>
    );
};