Search code examples
react-nativeglobal-variables

Unable to change global variable in React Native, are they read-only?


I am having the most difficult and frustrating time changing a 'global' variable in React Native. I am new to the language however this should be far simpler than it evidently is. It seems as if 'global' variables are 'read only' and cannot be changed...but I find that impossible to believe. Is it related to usage of React Navigation? Here is some code. First I create a .js file to hold my 'global' variable object:

//'globals.js'

module.exports = {
 STATUS: 'false',
};

Now my main code in 'app.js':

//'app.js'

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

GLOBAL = require('./globals');  //import the 'global' object and assign name

function HomeScreen({ navigation }) {

 return (
  <>
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center'    }}>
      <Text>Passed GLOBAL: {JSON.stringify(GLOBAL.STATUS)}</Text>  //indicates 'false'...as it should when running for the first time...
      <Text>Home Screen</Text>
    </View>
 {GLOBAL.STATUS === 'false' ? (
        <Button
          title="Go to Login"
          onPress={() => navigation.navigate('Login')}
        />
      ) : (
        <Button title="Do Stuff" onPress={() => navigation.navigate('StuffScreen')} />
      )}
  </>
 );

}

function LoginScreen({ navigation }) {
//do stuff to login here...
var _test = 'dwarves';
GLOBAL.STATUS = _test;

  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center'    }}>
      <Text>Stuff Screen</Text>
      <Text>Set Global: {JSON.stringify(GLOBAL.STATUS)}</Text>  //still indicates 'false' even after changing value, should be 'dwarves'...WHY????
      <Button title="Go to Home" onPress={() => navigation.navigate('Home')} />
    </View>
  );
}

function StuffScreen({ navigation }) {
//do stuff 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="Stuff" component={StuffScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;

can somebody explain why the 'GLOBAL.STATUS' value is NOT passed to the 'Home' screen when changed in another function...??? As a global variable this should be the case, however I am finding it impossible to achieve. Thank you for any suggestions on what I am not understanding about this.


Solution

  • This is a simple one, changing the value of any variable that is not part of some sort of state or props does not cause the React tree to re-render.

    The variable is being changed but your HomeScreen component never gets notified of that change and this is by design. Can you imagine the performance issues that we would be having if every variable assignment triggered re-renders?

    I suggest you look into the Context API, it allows you to expose values to all your components as well as notifying the necessary components when the values change.