2

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.

Pangit
  • 564
  • 1
  • 7
  • 23
  • Can you share what error you are getting? Also, the standard way of doing that in React is to pass `_secured` to the component as a prop, so if the value of `_secured` is updated, then the component will be rerendered – gzcz Jun 13 '20 at 21:45
  • Thanks for the response. My error is "Text strings must be rendered within a component". I used a global variable since the value of '_secured' could be changed within a separate function (such as 'LoginScreen')...that is why I did not use a prop within the 'HomeScreen' function...I would have thought usage of a global is the only way to accomplish this. – Pangit Jun 14 '20 at 19:10
  • Instead of using if statements, use a [ternary operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) like `_secured === 0 ? () : (`). I don't think you can use if statements in JSX – gzcz Jun 15 '20 at 02:02
  • OK thank you for the suggestion, I will look into that. I assumed using JavaScript would be suitable...I guess React Native doesn't like it as much as I had hoped. – Pangit Jun 15 '20 at 19:57
  • Gave the ternary operator a try however still having great difficulty. I have edited my original post above to reflect my difficulties for anybody that can provide some hints. Thank you. – Pangit Jun 19 '20 at 10:39

1 Answers1

1

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

}
Abdul Basit Rishi
  • 2,268
  • 24
  • 30
Maddy Blacklisted
  • 1,190
  • 1
  • 7
  • 17
  • Thank you for the reply. I will give this a try later when I have a chance. Regards. – Pangit Jun 19 '20 at 22:05
  • I have finally had a chance to try your suggestion, I do not get any errors as before and my 'Home' screen renders with a button that reads 'Go to login'...as it should. However it seems the 'onPress' is not functional now (onPress={() => navigation.navigate('Login')). If I were to simply place the button in the function without the ternary operator syntax it would route properly upon being pressed. Any idea what might be causing that routing functionality to be lost? Thanks again for your input. – Pangit Jun 20 '20 at 11:23