Search code examples
javascriptreact-nativeconditional-rendering

Display buttons dependent on variable value in React Native


I am using the following code to display a 'Home' page with a button on it in React Native...it is functional without difficulty:

import React, { useState } from 'react';
import { Button, Text, TextInput, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
     <Text>Home Screen</Text>
     <Button title="Go to Login" onPress={() => navigation.navigate('Login')} />
    </View>
  );
}

function LoginScreen({ navigation }) {
//do things to login here
}

const Stack = createStackNavigator();

function App() {
 return (
  <NavigationContainer>
   <Stack.Navigator>
    <Stack.Screen name="Home" component={HomeScreen} />
    <Stack.Screen name="Login" component={LoginScreen} />
   </Stack.Navigator>
  </NavigationContainer>
 );
}

export default App;

The problem arises when I try to modify the code to display a button on the 'Home' page dependent on the value of a global variable, I get an error. I am not sure why however it may be the 'HomeScreen' function does not recognize the value of the '_secured' variable...?

import React, { useState } from 'react';
import { Button, Text, TextInput, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

var _secured = 0; 

function HomeScreen({ navigation }) {
 return (
  <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
  <Text>Home Screen</Text>
   if (_secured === 0) {
   <Button title="Go to Login" onPress={() => navigation.navigate('Login')} />
   } else {
   <Button title="Stuff" onPress={() => navigation.navigate('DoStuff')} />
   }
  </View>
 );
}

function LoginScreen({ navigation }) {
//do things to login here
}

function StuffScreen({ navigation }) {
//do other things here
}

const Stack = createStackNavigator();

function App() {
 return (
  <NavigationContainer>
   <Stack.Navigator>
    <Stack.Screen name="Home" component={HomeScreen} />
    <Stack.Screen name="Login" component={LoginScreen} />
    <Stack.Screen name="DoStuff" component={StuffScreen} />
   </Stack.Navigator>
  </NavigationContainer>
 );
}

export default App;

Any suggestions greatly appreciated, I am new to React Native. I thank you in advance.

Unfortunately I am still having immense difficulty trying to figure this out, it is incredibly frustrating. I believe I need to define my 'global' variable using the 'useState'. My code for the 'Home' screen is as follows:

function HomeScreen({ navigation }) {
const [isLogged, setLog] = useState(0);

 return (
  <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
   <Text>Home Screen</Text>

  </View>
 );
(isLogged === 0) ? (<Button title="Go to Login"> onPress={() => navigation.navigate('Login')} </Button>) : (<Button title="Stuff"> onPress={() => navigation.navigate('DoStuff')} </Button>)
}

As previously mentioned I am new to developing for React Native. The inability to use simple if/else statements to accomplish this is extremely disheartening. I thank anybody in advance for some insight.


Solution

  • Just like an ordinary function, react renderer cannot return more than one JSX element. So wrapping up your original code inside a single JSX EmptyView <></> and then using JS to evaluate conditions and finally returning a button view.

    function HomeScreen({ navigation }) {
    const [isLogged, setLog] = useState(0);
    
     return (
      <>
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
          <Text>Home Screen</Text>
        </View>
        {isLogged === 0 ? (<Button title="Go to Login" onPress={() => navigation.navigate('Login')} > </Button>) : (<Button title="Stuff" onPress={() => navigation.navigate('DoStuff')} > </Button>)}
      </>
     );
    
    }