1

I am still somewhat new to React Native. I am attempting to detect the user's Internet connectivity status and display a button based upon the result. I would like to exit the app if no Internet connection is detected. My full code is as follows.

import React from 'react'
import { Button, StyleSheet, Text, View } from 'react-native'
import { Actions } from 'react-native-router-flux'
import FlatContainer from './components/FlatContainer';
import NetInfo from "@react-native-community/netinfo";

const Welcome = () => {

NetInfo.fetch().then(state => {
  console.log("Connection type", state.type);
  console.log("Is connected?", state.isConnected);
  var _connection = JSON.stringify(state.isConnected)
});

   const goToHome = () => {
      Actions.home()
   }

   return (
    <View style={styles.page}>
      <FlatContainer style={styles.container1}>
          <Text>Welcome!</Text>
      </FlatContainer>
      <FlatContainer style={styles.container2}>

        {_connection === "true" ? (
          <View style={styles.button}>
            <Button title='Button' color='blue' onPress={goToHome}/>
          </View>
        ) : (
         <View style={styles.button}>
            <Button title='Exit' color='blue'/>  //use 'BackHandler' here to exit?
         </View>
        )}

      </FlatContainer>
      <FlatContainer style={styles.container3}>
          <Text>image</Text>
      </FlatContainer>
    </View>
   )
}



const styles = StyleSheet.create({
  page:{
    flex:1,
    paddingTop:50,
    backgroundColor: 'black'
  },
  container1: {
    backgroundColor: 'black',
    height : 100
  },
  container2: {
    backgroundColor: 'black',
    height : 100
  },
  container3: {
    backgroundColor: 'black',
    height : 100
  },
  button:{
    width:80,
    height:40,
    color: 'white',
    backgroundColor: 'white'
  }
});


export default Welcome

The problem is that although the "NetInfo" seems to properly work to determine an Internet connection status, it seems I am unable to transfer that information to a variable ("_connection"). That variable is used to determine which button to display. The "_connection" seems to not be recognized.

In addition I believe I would need to import the "BackHandler" module to write code to allow the user to exit the app upon pressing the proper button, however I have not written that part yet since my code crashes due to the unrecognized variable. Any advice greatly appreciated. Regards.

After some input from others and some research my code is as follows, it seems functional as written here:

const Welcome = () => {

const [isConnected, setIsConnected] = useState(false);  //assume NO Internet connectivity...
const netInfo = useNetInfo();

  useEffect(() => {    
  setIsConnected(netInfo.isConnected);  
  });

const goToHome = () => {
  Actions.home()
}

const buttonToShowIfConnected = <Button title='Home' color='blue' onPress={goToHome}/>
const buttonToShowIfNotConnected = <Button title='Exit' color='blue' onPress={goToHome}/>
let conditionalButton = isConnected ? buttonToShowIfConnected : buttonToShowIfNotConnected

return (
<View style={styles.page}>
  <FlatContainer style={styles.container1}>
      <Text>Welcome</Text>
      <Text>Type: {netInfo.type}</Text>
      <Text>Is Connected? {netInfo.isConnected.toString()}</Text>
  </FlatContainer>
  <FlatContainer style={styles.container2}>

{conditionalButton}

  </FlatContainer>
  <FlatContainer style={styles.container3}>
      <Text>image</Text>
  </FlatContainer>
</View>
)
}


const styles = StyleSheet.create({
//stuff
}
Pangit
  • 564
  • 1
  • 7
  • 23

2 Answers2

2

I think you need to declare a variable with useState() and use useNetInfo() to transfer that variable .Then

 const netInfo = useNetInfo()

  useEffect(() => {
    const unsubscribe = NetInfo.addEventListener((state) => {
      setIsConnected(state.isConnected)
    })
    return (
      () => unsubscribe()
    )
  }, [])
Dharman
  • 30,962
  • 25
  • 85
  • 135
Lawson
  • 36
  • 3
  • Thanks for the reply. This could be a viable option in addition to the above answer as well. Can you explain why the second parameter in the function is "[]"...? That confuses me greatly about 'useEffect' functions. Thank you again. – Pangit Dec 09 '20 at 16:47
  • It has a role like ComponentDidMount and NetInfo.addEventListener it is enough to be called once . Whenever the state changes, we update it again – Lawson Dec 09 '20 at 16:53
  • Thanks for your explanation, I think I get it. Also I appreciate your input on the initial response, I tried it and found there was a syntax error in your code. However it was helpful in some additional research I did. Regards :) – Pangit Dec 11 '20 at 12:59
  • Okay. Good luck to you :> @Pangit – Lawson Dec 11 '20 at 13:37
1

I think the problem is _connection only has scope inside the .then() block, so when you try to access it outside of that block, in your conditional, it's undefined.

I've never used the NetInfo package, but something like this might work:

const Welcome = () => {
  // pass true or false to `useState` here depending on whether or not
  // you want to assume the client is or isn't connected by default
  const [isConnected, setIsConnected] = useState() 

  useEffect(() => {
    NetInfo.fetch().then(state => {
      setIsConnected(state.isConnected)
    }
  })

  // skipping other code
  const buttonToShowIfConnected = // your markup goes here
  const buttonToShowIfNotConnected = // your markup goes here
  let conditionalButton = isConnected ? buttonToShowIfConnected : buttonToShowIfNotConnected

  return (
    // markup before button
    {conditionalButton}
    // markup after button
  )
}

That's not the only way to do it, but in general, I think the problem is variable scope and maybe not fully understanding state in React.

Jim J
  • 546
  • 3
  • 11
  • Thanks for the reply. I will give this a try later when I have a chance. In your code is the "buttonToShowIfConnected" and "buttonToShowIfNotConnected" I am assuming this is written with the 'button' definition, i.e. my code above such as " – Pangit Dec 09 '20 at 16:43
  • I'm not an expert but, at a glance, the button markup looks OK. – Jim J Dec 09 '20 at 16:54
  • 1
    Thanks again. I found a syntax error in the code sample you had provided. However I did some additional research and was able to get something functional. I posted my working code in the above edit. Regards :) – Pangit Dec 11 '20 at 13:01