A have a react application using a single page. I call index.html and use ajax(axio) and update the page. I do not use any routing.
I have some global variables and will use in the whole scope of the application. The variables are primitive type integer for example. Some of the variables may be updated during the app lifecycle and some remain constant. But I should be able to reach them from all react components/javascripts. They may contain business related constants or example decimal format mask, keeping them private in each component will not be useful.
There is no need/reason to store it on the disk (localStorage).
Question is: what is the best way (performance etc) storing the global variable foo in the app?
window.foo = 10 or
window.sessionStorage.foo = 10
AFAIK, window.foo is for a single page and sessionStorage allows using within multiple pages within the same origin. What is best in my case when I use a single page? Are there any other drawbacks of window.foo usage? Security is not important, the vales stored are not sensitive. Most critical is the performance.
You probably want to use context rather than either of those. From that documentation:
Context is designed to share data that can be considered “global” for a tree of React components, such as the current authenticated user, theme, or preferred language.
Definitely don't use global variables. The global namespace is incredibly crowded, and adding to it is generally not best practice. If you did use a global for this, I'd recommend using just one, and having it refer to an object with properties for the various pieces of information you want to share. Note that they'll be window-specific.
One reason to possibly consider using sessionStorage (or perhaps periodically synchronizing your React context to it) is if you want changes in one window to be reflected in another window. Two windows/tabs from the same origin share the same sessionStorage and can get an event (storage) when the other one changes that storage. So if the global information were an app theme (say, light vs. dark), changing it in one tab could also affect the other tab if you respond to the storage event by updating your React context. Note that sessionStorage (and localStorage) only store strings, so the usual thing is to convert to JSON when storing (JSON.stringify) and from JSON when loading (JSON.parse).
Related
It seems like a crazy idea, but is there any problem if I use globalThis to store the global state of my browser only SPA.
I am thinking of something like this
globalThis.state = {...initialStateData}; // attach a property to globalThis and initialize
//later in any component, mutate the value
globalThis.state.counter = 45;
//yet in some other area, access and display the value
console.log(globalThis.state.counter);
This can be taken further by introducing proxies into the mix and create something like a light weight redux.
I tested this in chrome, and it works (by works I mean chrome had no objection on me attaching my data to globalThis).
My question is, is it a crazy idea and should not be used in a production app because of some standards that I might be violating in ignorance?
Or perhaps, behaviour of globalThis is gonna change over time and browsers will not allow user-attached attributes to this specific object?
EDIT: This question is about pure vanilla JS and not about redux or react or even typescript.
How to define global variable in Deno? will be the closest match to the current query
Modifying the globalThis or the window object of browser is quit non-conventional & it would create some issues that'd be hard to debug or fix.. Also this is one kind of object pollution & eslint/jshint will also complain about & typescript will throw Compile Time Error.. Don't do this in production as it'd be very bad in the long run.. One of them is conflicting property names & there are many problem that will arise. I don't know each & every one of them but you can easily read some medium books/articles about this behavior. Also that's why modern npm packages doesn't touch these objects as globalThis doesn't allow the idea of modules... Try using globalThis/window as read-only objects.. Don't mutate the props of it..
Hope you understand what I said..
It is generally not recommended to modify globalThis (or window) for the following reasons:
Naming Conflicts with 3rd party code: If another script also modifies globalThis and chooses the same name, you're in trouble, though this applies more to libraries than the main page's logic.
Naming Conflicts with Javascript: New built-in javascript utilities tend to get added to the global object - if they ever added one with the same name you're using, it'll cause issues, both in your page, and any library you use that expects that utility to be there. However, as long as your name is unique enough, this really isn't a big issue.
Versioning: If you're developing a library, there are unfortunately scenarios where you might have multiple versions of the same library loaded at once. This is not possible if they use global state. Again, this doesn't really apply to use as you're not developing a library.
Traceability: It's difficult to know what sets the global state and what modifies it.
So, in all honesty, you can probably get away with using global state and not face any of those negative consequences. I don't want to just tell you not to use it simply because that's the recommended advice. In fact, back in the day, it used to be more common for websites to put all of their data and modules into one giant global hierarchy. However, I would still recommend avoiding global state for one other reason - A better solution exists that's less magical. Javascript now has a standard module system that can be used in place of global state. Just create a module to hold whatever shared state your application has.
In a Google spreadsheet using the Script Editor, I do function calls, but I am not quite sure if the best way to store persistant data (data that I will continue to use) is to use global variables (using objects, arrays, strings), or there is a better way to store data.
I don't want to use cells which could be another way.
Another question, is it possible to create (pseudo) classes in this environment? Best way?
Both ScriptProperties and ScriptDB are deprecated.
Instead, you should be using the new class PropertiesService which is split into three sections of narrowing scope:
Document - Gets a property store that all users can access within the current document, if the script is published as an add-on.
Script - Gets a property store that all users can access, but only within this script.
User - Gets a property store that only the current user can access, and only within this script.
Here's an example persisting a user property across calls:
var properties = PropertiesService.getScriptProperties();
function saveValue(lastDate) {
properties.setProperty('lastCalled', lastDate);
}
function getValue() {
return properties.getProperty('lastCalled');
}
The script execution environment is stateless, so you cannot access local variables from previous runs, but you can store getScriptProperties() in a local variable because it will be re-run for each return trip to the server so it can be called in either method.
If you need to store something on a more temporary basis, you can use the CacheService API
Persistent data can be stored using the Class ScriptProperties:
http://code.google.com/googleapps/appsscript/class_scriptproperties.html
All values are stored as a string and will have to be converted back with the likes or parsInt or parseFloat when they are retrieved.
JSON objects can also be stored in this manner.
My experience has been that every query to retrieve or store values takes a long time. At the very least, I would cache the information in your javascript code as much as possible when it is safe. My scripts always execute all at once, so I don't need to keep global variables as I simply pass the retrieved data arrays around, manipulate them, and finally store them back in one fell swoop. If I needed persistence across script invocations and I didn't care about dropping intermediate values on close of the webpage, then I'd use globals. Clearly you have to think about what happens if your script is stopped in the middle and you haven't yet stored the values back to Google.
React has a feature called Context which advertises a way to store globally accessible values without having to pass them down as props.
What is unclear to me is what advantages this has over storing values on the window. If on my page I have window.current_user = user_details, the user details are now available to all react components. What would the advantages be to moving this in to React's context?
If a variable on window changes, React won't know, so it can't re-render pieces of your app that depend on that data.
With context, any changes to the data will trigger re-renders.
There are arguably other advantages, but in my opinion, the re-render difference makes the two options basically apples and oranges.
On the other hand, Context isn't truly "global," because the Consumer (where you read the data) has to be somewhere beneath the Provider (where the values are written) in the hierarchy. This would make Context unsuitable, for example, in an app where the Settings menu was way down in the component hierarchy, but settings consumers were peppered throughout the app, as there's no way to pass values "up" using context.
So, if the data you're interested in doesn't change often (or at all) after the app's initial render, my opinion is that window could be more suitable than Context. Some folks will argue that this clogs up the window object, or that it violates other (usually sound) design principles, but in my opinion, if you understand the tradeoffs, using window can be a perfectly pragmatic decision.
I'm wondering which would be better practice. Polluting the global namespace with global variables for intra-session persistence or using localStorage instead?
So in other words set a global variable on launch, change its value in a function when required and reference it in a third function, or use localStorage.setItem then localStorage.removeItem when the value is no longer needed?
Will doing either one increase memory efficiency?
LocalStorage is primarily for persistent data across sessions.
In your case, as your looking for an intra-session persistence, global variables have clear advantages.
I will start with cons of global variables first.
It uses the global namespace, any third party js code can manipulate it
A page refresh can wipe off your data
Well, that's it. If we consider the cons of LocalStorage, the list will raise your eyebrows.
set and get are slow and can be a performance bottleneck for large datasets
only strings are allowed; you may have to serialize your data before setting
I would surely vote up for LocalStorage if your use case involved inter-session storage. However, in your scenario, the only benefit you see is the removeItem function for which you have the delete counterpart for global variables.
This article may be helpful: http://www.sitepoint.com/html5-browser-storage-past-present-future/
As now consider to using DI in frameworks like Angular.
I have a web app, which has 2 html pages(html1,html2 related to javascript file js1.js,js2.js)
When I click a button on html1, it will navigate to html2.
I know there is the way transfer the parameter using url from html1/js1/js to html2/js2.js.
Is there a mechanism that set up variables both j1.js j2.js can access?(likes global variable in c)
Welcome any comment?
This is not directly possible as each page loads with its own window object namespace.
i.e. A global variable in js1.js (used in page1.html) is actually a member of the window object in page1. Similarly a global variable in page2.html is a member of that page's window object. The 2 window objects are totally different in the sense there is no site wide window or site object that can store global variable for use throughout a site
You can however use window.localStorage to share variables/values across pages in your site.
Example:
Setting value:
window.localStorage.setItem('myglobal', "hello");
Getting value:
var myglobal = window.localStorage.getItem('myglobal');
A hackish solution is to store it into the window.name field. This is shared in the same window/tab of the browser.
I personally don't like it. That variable isn't meant to be used this way.
There are libraries to persist state: http://pablotron.org/?cid=1557
Or, you could write your own code to store the variable in session (requires server-side programming), in HTML5 storage, in cookies, etc.
Variables and values can be passed through pages via querystring.
Have a look at this SO article.
If you strictly need to create a Javascript global variable, then you have to include a common snippet in both pages:
var myGlobalVar;
But this only represent a storage accessible by both scripts. You have to set its value anyway.
You can either parse window.location.href to extract the parameters, set cookies in one page and retrieve them in the other (example here) which also requires parsing or use a server-side solution.
Most probably if you look for in interwebs you can find parsers for URLs and Cookies.