If you truly want a global variable (not advisable, of course) then you're always 100% free to do
window.globalVar = 0;
in any of your modules.
The more robust solution would of course be to have this global variable sit in some sort of dedicated module, like
globalVar.js
export default {
value: 0
};
and then you could
import globalVal from './globalVar';
globalVal.value = 'whatever';
from any modules needed.
The only risk would be that webpack might duplicate this same "global" value into multiple bundles if you're code splitting, depending on your setup. So separate module would be using their own local copy of this not-so-global variable. EDIT - this isn't true. webpack never did this; that comment was based on a misunderstanding on my part.
Answer from Adam Rackis on Stack OverflowBeyond React
You might not be aware that an import is global already. If you export an object (singleton) it is then globally accessible as an import statement and it can also be modified globally.
If you want to initialize something globally but ensure its only modified once, you can use this singleton approach that initially has modifiable properties but then you can use Object.freeze after its first use to ensure its immutable in your init scenario.
const myInitObject = {}
export default myInitObject
then in your init method referencing it:
import myInitObject from './myInitObject'
myInitObject.someProp = 'i am about to get cold'
Object.freeze(myInitObject)
The myInitObject will still be global as it can be referenced anywhere as an import but will remain frozen and throw if anyone attempts to modify it.
Example of react state using singleton
https://codesandbox.io/s/adoring-architecture-ru3vt (see UserContext.tsx)
If using react-create-app
(what I was looking for actually) In this scenario you can also initialize global objects cleanly when referencing environment variables.
Creating a .env file at the root of your project with prefixed REACT_APP_ variables inside does quite nicely. You can reference within your JS and JSX process.env.REACT_APP_SOME_VAR as you need AND it's immutable by design.
This avoids having to set window.myVar = %REACT_APP_MY_VAR% in HTML.
See more useful details about this from Facebook directly:
https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables
Why don't you try using Context?
You can declare a global context variable in any of the parent components and this variable will be accessible across the component tree by this.context.varname. You only have to specify childContextTypes and getChildContext in the parent component and thereafter you can use/modify this from any component by just specifying contextTypes in the child component.
However, please take a note of this as mentioned in docs:
Just as global variables are best avoided when writing clear code, you should avoid using context in most cases. In particular, think twice before using it to "save typing" and using it instead of passing explicit props.
Is there any way in react, where we have some global variable in a file and after that build we can change those variables and the app works smoothly ?
How to declare global variables to be used throughout the app?
How to declare global variables in React JS
Global Variables
Quite a lot of clarifications are required to explain what happens in your code but i'll try to be succinct.
Having it your way
global.js
Is not really global but a module, and exported members are read-only.
You could make it work by exporting an object:
export let myGlobal = { count: 0 };
And changing your onClick handler to
() => { myGlobal.count++ }
But your components won't re-render, since it's not part of the state, and therefore the change won't be noticed by React.
The React way
If you want to share state between components - you should either lift the state up or use the context API as described in this answer
In raw javascript project, you can export a global variable in a file, and import anywhere in other files. That's what you did.
But in React, if you want to use a global state, you should use context API. Your code does not run because myGlobal is not declared as a state. Thus, React cannot track its state.
The correct method is like this:
const {useState, useContext} = React;
// you can create context outside of React component
const CounterContext = React.createContext(0);
// export default CounterContext;
// import CounterContext from 'global/counter-context';
const ChildComponent = () => {
const counter = useContext(CounterContext);
return (
<div className="other-component">
<p>This is Child Component that consumes CounterContext value </p>
<p>Current counter is: {counter}</p>
</div>
);
};
// import CounterContext from 'global/counter-context';
const App = () => {
const [counter, setCounter] = useState(0);
return (
<div className="app">
<CounterContext.Provider value={counter}>
<p>This is Context Provider component. Global state is maintained here and you can consume the state value in any other child components</p>
<label>Click this button to increment global counter state: </label>
<button onClick={() => setCounter((oldCounter) => (oldCounter + 1))}>
Increment
</button>
<ChildComponent />
</CounterContext.Provider>
</div>
);
};
class Root extends React.Component {
render() {
return (<App />);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
.app {
border: 1px solid red;
padding: 5px;
margin: 5px;
}
button {
margin-bottom: 5px;
margin-left: 5px;
}
.other-component {
border: 1px solid blue;
padding: 5px;
margin: 5px;
}
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<div id="root">
</div>
Hooks API Reference
My app uses a few json objects which will never change, that are fetched by ajax. What is the best way to declare these, and easily make them accessible throughout the app? Obviously the ajax needs to finish before the app is rendered, but I suppose because they don't change, they shouldn't be stored in the state?
Thanks
The global scope in React Native is variable global. For ex: as global.foo = foo, then you can use global.foo anywhere as a global variable.
The global scope may be used to store the global config or similar things. Share variables between different views, as your description, you can choose many other solutions(use redux,flux or store them in a higher component), the 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
Have a look at react Context :
https://reactjs.org/docs/context.html
simple example:
const ThemeContext = React.createContext('name');
if you are using react 16.2 and lower use this legacy react context:
https://reactjs.org/docs/legacy-context.html
You can declare a global context variable in any of the parent components and this variable will be accessible across the component tree by this.context.name. You only have to specify childContextTypes and getChildContext
or if you want the "ugly" way, do this: inside vars.js
declare var Name = 'empty';
export default window.Name;
then import './vars' in the file that contains "DataAreaOne" and "DataAreaTwo"
import Name from './vars';
then inside the class
name = Name;
and use it like so
...
if(this.name != "something"){
...
Your use case here will be consumed by something outside of React (an Apollo Link), so Context does not make any sense here - Context would make a value available to children in the React tree, but your link is not a child in a React Tree.
Instead you can just export an object and modify that object (you probably cannot reassign it depending on how you import/export it, but you can always modify it).
// index.js
export const globalData = {
auth: null
}
// anywhere else
import { globalData } from './index.js'
globalData.auth = "foo"
That said, you can only work with global data like this if you are not using SSR. If you are using SSR (e.g. in a Client Component in Next.js), you'd need to find another way of doing that.
In that case, you could use Apollo CLient's defaultContext.
if u want to store a variable globally u can use context api or redux-tool kit here i am giving a rough idea how u can achieve this using context API first Create A folder usually context.. inside this create a file usually name as DataProvider.jsx and do thing like this
import { createContext, useState } from 'react';
export const DataContext = createContext(null);
const DataProvider = ({ children }) => {
const [Client, setClient] = useState([]);
return (
<DataContext.Provider value={{
Client, setClient
}}
>
{children}
</DataContext.Provider>
)
}
export default DataProvider;
next step u should wrap your app.js like this
import DataProvider from './context/DataProvider';
function App() {
return (
<DataProvider>
<Home />
</DataProvider>
);
}
export default App;
now u can setclient or u can use client data like below
assume u have a file name Client.jsx where u want to set the client data
const { setCleint} = useContext(DataContext)
set the Client data to setClient just as normal state now in similar way u can render the client list anywhere like this
const { Cleint} = useContext(DataContext);