[react-native] How to use global variables in React Native?

In React Native I want to use global variables when I am moving between different screens

Can anyone help me how to achieve it?

This question is related to react-native

The answer is


The global scope in React Native is variable global. Such as global.foo = foo, then you can use global.foo anywhere.

But do not abuse it! In my opinion, global scope may used to store the global config or something like that. Share variables between different views, as your description, you can choose many other solutions(use redux,flux or store them in a higher component), global scope is not a good choice.

A good practice to define global variable is to use a js file. For example global.js

global.foo = foo;
global.bar = bar;

Then, to make sure it is executed when project initialized. For example, import the file in index.js:

import './global.js'
// other code

Now, you can use the global variable anywhere, and don't need to import global.js in each file. Try not to modify them!


You can use the global keyword to solve this.

Assume that you want to declare a variable called isFromManageUserAccount as a global variable you can use the following code.

global.isFromManageUserAccount=false;

After declaring like this you can use this variable anywhere in the application.


Set up a flux container

simple example

import alt from './../../alt.js';

    class PostActions {
        constructor(){
        this.generateActions('setMessages');
        }

        setMessages(indexArray){
            this.actions.setMessages(indexArray);
        }
    }


export default alt.createActions(PostActions);

store looks like this

class PostStore{

    constructor(){

       this.messages = [];

       this.bindActions(MessageActions);
    }




    setMessages(messages){
        this.messages = messages;
    }
}

export default alt.createStore(PostStore);

Then every component that listens to the store can share this variable In your constructor is where you should grab it

constructor(props){
    super(props);

   //here is your data you get from the store, do what you want with it 
    var messageStore = MessageStore.getState();

}


    componentDidMount() {
      MessageStore.listen(this.onMessageChange.bind(this));
    }

    componentWillUnmount() {
      MessageStore.unlisten(this.onMessageChange.bind(this));
    }

    onMessageChange(state){ 
        //if the data ever changes each component listining will be notified and can do the proper processing. 
   }

This way, you can share you data across the app without every component having to communicate with each other.


The way you should be doing it in React Native (as I understand it), is by saving your 'global' variable in your index.js, for example. From there you can then pass it down using props.

Example:

    class MainComponent extends Component {

        componentDidMount() {
            //Define some variable in your component
            this.variable = "What's up, I'm a variable";
        }
        ...
        render () {
            <Navigator
                renderScene={(() => {
                    return(
                        <SceneComponent
                                //Pass the variable you want to be global through here
                                myPassedVariable={this.variable}/>
                    );
                })}/>
        }
    }


    class SceneComponent extends Component {

        render() {
            return(
                <Text>{this.props.myPassedVariable}</Text>
            );
        }

    }

If you just want to pass some data from one screen to the next, you can pass them with the navigation.navigate method like this:

<Button onPress={()=> {this.props.navigation.navigate('NextScreen',{foo:bar)} />

and in 'NextScreen' you can access them with the navigation.getParam() method:

let foo=this.props.navigation.getParam(foo);

But it can get really "messy" if you have more than a couple of variables to pass..


Try to use global.foo = bar in index.android.js or index.ios.js, then you can call in other file js.


You can consider leveraging React's Context feature.

class NavigationContainer extends React.Component {
    constructor(props) {
        super(props);
        this.goTo = this.goTo.bind(this);
    }
    goTo(location) {
        ...
    }
    getChildContext() {
        // returns the context to pass to children
        return {
            goTo: this.goTo
        }
    }
    ...
}

// defines the context available to children
NavigationContainer.childContextTypes = {
    goTo: PropTypes.func
}

class SomeViewContainer extends React.Component {
    render() {
        // grab the context provided by ancestors
        const {goTo} = this.context;
        return <button onClick={evt => goTo('somewhere')}>
            Hello
        </button>
    }
}

// Define the context we want from ancestors
SomeViewContainer.contextTypes = {
    goTo: PropTypes.func
}

With context, you can pass data through the component tree without having to pass the props down manually at every level. There is a big warning on this being an experimental feature and may break in the future, but I would imagine this feature to be around given the majority of the popular frameworks like Redux use context extensively.

The main advantage of using context v.s. a global variable is context is "scoped" to a subtree (this means you can define different scopes for different subtrees).

Do note that you should not pass your model data via context, as changes in context will not trigger React's component render cycle. However, I do find it useful in some use case, especially when implementing your own custom framework or workflow.