Say, there are two tabs with the same webpage open. On one tab, I make some change in localStorage, then, when I go to the other tab, I'd like to see that change without having to reload the page.
One way that I have thought to do this is by using a setInterval method, but for my application I don't really need to check for updates every 3-5 seconds so I don't feel this approach is ideal.
I am using React. TLDR: Is there a good way to update data as soon as I open the tab of a previously-loaded webpage?
Side Note For iOS Folks: On iOS, there is a viewDidLoad method (which from my understanding is similar to componentDidMount), and there is a viewDidAppear method (so I am basically, asking for the React/JS version of viewDidAppear?)
In regards to the possible duplicate question: To me, it seems fairly different, and this question is more React.js focused.
Use the page visibility api or just window's focus event. I recommend having a backup timer set to a minute or so... these events can be finicky.
There's nothing react specific about it other than binding to global events.
You can use jQuery and listen to localStorage on-change events:
$(window).bind('storage', function (e) {
console.log(e.originalEvent.key, e.originalEvent.newValue);
});
This way, once a key in the local storage changes, you can reflect it in the 2nd tab.
If you're using react, then make sure you're rendering a component in your main component's render() function that makes use of you main component's state object. Once local storage has changed, update the state accordingly and react will take care of the rest.
I added the following lines of code to my main component.
In componentDidMount:
document.addEventListener("visibilitychange", this._callbackFunc, false);
In componentWillUnmount:
document.removeEventListener("visibilitychange", this._callbackFunc, false);
Related
I'm doing a Chrome plugin for Facebook and I want to modify a post using external javascript. I can change the textContent of a span but the state is not changed and the Save button is not activated.
The html looks like that :
<div class="" data-block="true" data-editor="1477r" data-offset-key="a699d-0-0">
<div data-offset-key="a699d-0-0" class="_1mf _1mj">
<span data-offset-key="a699d-0-0">
<span data-text="true">test</span>
</span>
</div>
</div>
The component in React Developper Tools :
[
I profiled a change of the text and this is the result for a 6 ms timeline activating the save button.
There are ways to modify a React input but did not found ways for my problem :
https://github.com/facebook/react/issues/11488
https://github.com/facebook/react/issues/10135#issuecomment-314441175
How can you change a Facebook post and his state with external javascript?
What would you do?
That’s not possible, you can’t imperatively mutate a React element tree from outside the app. You’d have to declaratively render a tree, either by modifying Facebook’s frontend code (beware of legal ramifications) or implementing your own post UI.
While it's nearly impossible to change the state of React component from your plugin, nothing stops you from emulating user's input by sending keystrokes, mouse clicks etc. The only thing you need it to figure out - which DOM-element listens to these events (not necessary one of those 4 in you question).
About the possibility of direct state change: let's say the component you need to changes is a functional one. Then it has a form of
Component() {
const [state, setState] = useState(...)
...
setState(something)
...
}
so you need to somehow access the setState function of the component. But how? It's private to the function call. If you think that instead you can call the useState directly, then be aware that in another component it will return another setState. I have no idea what would happen if you'll call useState outside of a component, but surely it will not be able to guess which setState you want.
If you want you can check the source code of react-devtools to find out how you can dig out the state from the depths of React... but would you really want to try? And for what? The next time Facebook or React will be updated your code will definitely break.
I'm trying to add an event listener onunload to dispatch a Vuex store action, letting me know the ID of the window being closed. (This is an app where we need to limit how many tabs are open because of resource consumption - its doing some virtualization/emulation stuff.)
I was able to successfully get a simple onunload event listener firing lifted almost directly from the MDN page on that.
window.addEventListener("beforeunload", function(event) {
event.preventDefault();
// problem line
this.$store.dispatch('CURR_TERMINAL_ACTION', this.id)
})
It seems like the store and the window object aren't going to be able to communicate with each other since I kept getting undefined on store, even when I tried passing it as an argument to this function thinking maybe I could provide access that way.
On a related note: I had thought that maybe I could try to accomplish this with a destruction lifecycle hook oF Vue, instead. (beforeDestroy(), probably.) However, each time this component is launched, it gets launched into a new browser tab. When I close out of that tab, it doesn't appear to trigger component destruction. After looking at the docs, it looks like you manually have to destroy components, otherwise they only get unmounted. I don't think my original onunload event can interact with $destroy either, if it can't access $store.
In your code this refers to window, or something but your vue-component. Then, you need to create another variable to get your vue-componentreference.
let that = this
window.addEventListener("beforeunload", function(event) {
event.preventDefault();
// problem line
that.$store.dispatch('CURR_TERMINAL_ACTION', that.id)
})
My native app support multi-language functionality like 'English' and 'Danish'. For this I have created a drop down on top of the header with two menu options, for example if click on Danish language,it will set the 'Danish' language, but the effect is not displayed, for this I have to click on current menu, then the effect of the language is seen.
So my questions is how to reload current page in react native programmatically.
Thanks in advance.
Try storing your locale in Redux and then update the UI from that state using container components.
I don't think your problem is reloading. You must change the state on click, but believe me do not write custom localization. Here is the great plugin to do it https://github.com/stefalda/ReactNativeLocalization
The correct way to cause a render of a page is by calling this.setState(). This will trigger the React lifecycle.
You don't need reload current page if you only need to change language, You can achive that with this library https://github.com/derniercri/react-native-redux-i18n
I want to execute a piece of code every time a new the page in navigated to. I am using the <page-router-outlet>.
As mention here, while using page-router-outlet the component is cached. So when it is navigated back into view no Init lifecycle events of angular 2 are executed.
I tied using just the , which does not cache the component and as a result call the Init Lifecycle events. But using it exits the app when I press the Hardware back button.
The site you linked to also mentions this: "What you can do is inject Page inside your component and attach to page navigation events (for example navigatedFrom) and do the cleanup there." Those events are listed here, especially the "navigatedTo" event seems relevant for your usecase.
How can I change the URL in ember without triggering a DOM update.
IE something like
window.location.hash = '/items/20';
However without triggering Embers routing system and the resulting DOM changes.
Note I'm currently using the hashlocation but intend to switch to history location
Background reading
http://emberjs.com/api/classes/Ember.Location.html
http://emberjs.com/api/classes/Ember.HashLocation.html
Why I want to do this in the first place (Item modal interface)
Well this took a lot of digging through the source, but here goes:
EmberApp.Router.router.updateURL('/item/10')