I'm working on a project using react with flux architecture.
I have several views and a store called ContextStore in which I save the current view in the state, so that when an action to change the view is triggered this store change his state and the Main view listen and change it.
But the problem is that always when I refresh the page with F5 it always goes to the initial Views.
What is more, if I press the back button the View has no change.
I think that my problem is because when I refresh the Main view loads again the initial state. How could I solve it?
Thanks!
You might want to look into using a router to manage your views. Here's the one I use: https://github.com/rackt/react-router. When you transition to different views (routes) it adds to the history stack so you can use the back button. However, I don't have the use case where you need to stay on the current view when you refresh, so you might need to use cookies or session storage in those instances in any case.
You are right, when hitting F5 you are completely reseting all javascript, ergo the store looses its state. You need to use some kind of storage for saving the state. Classical ways are cookies, or you could use IndexedDB which is included into HTML5
Related
I'm working on a form in VueJS and want the user to be able to confirm the contents before submission.
This involves routing from form page -> confirm page.
However, when I have the user go back the state of the previous page is reset.
Is there a way I can cleanly preserve the state of the previous page without digging far into the store's state?
Or is this approach against the principles of Vue?
Previous approach tried is to save the form's state when moving to the confirm screen.
Then when moving back the previous state is restored by checking if the data exists on create, e.g.
onCreated() {
this.myFormData = this.$store.state.[myFormModuleName].formData ? this.$store.state.[myFormModuleName].formData : setSomeDefaultInstead();
}
And while this works it feels hacky and is difficult to test.
This may need editing for being too broad, but is there a 'best practice' approach between Vue for maintaining state between pages as you can do in Angular? Or are plugins the only way to go?
As mentioned above, I would like to ensure that the approach used doesn't break pre-existing tests for the form.
Without having the entire code available, I think you best bet might be a <keep-alive> component around your router-view, have a look at the section in the docs here: https://v2.vuejs.org/v2/api/#keep-alive
This should preserve the entire local state of your component when it's being used again.
For a consistent user experience, I'd like my react app to reverse its state when the user clicks the browser back button.
For example, if I change an element in the state with a function call:
changeVar = (idx) => (event) => {
this.setState({thisIndex: idx});
//how to notify browser stack of this change?
}
How could I add this to the browser stack so that users can click the back button in the browser to reverse the state change?
So in general question is "how could I handle browser Back/Next button clicked?" or "How could I react on user navigates through history?"
Here such a thing like History API with its .pushState comes to the scene.
In short:
on each significant state change you call history.pushState(stateData)
once user clicks Back button it does not actually navigate away to different URL rather change current state only(but only if previous state in the stack has been created with .pushState or .replaceState)
your code detects if history navigation occurs(Back button been clicked) by listening to popstate event
based on appropriate state data that you read from history.state you restore application state appropriately
So far the last question is how to put all the data across your application in single object and to restore all the application with it modules' states later. And here redux comes to the help. Redux suppose you have just single Store over all your application. In other words all the state is already contained in single object that you just need to pass into .pushState() to store and to restore it after Back button is clicked.
PS remember I told about significant change? since "all the data all over the application" is large enough it would make overhead to store store it million times in the memory. Also it would be a silly if clicking Back button say just collapse a dropdown.
PPS and since history is global there is no way to store/restore state on per-component way. so maybe(just maybe) it's better to implement something like "state change history" for your component and propose user some different control to restore its state(instead of clicking Back button in browser)
I have a parent view with a nested view in the middle.
On a state change, the nested view seems to stick for a second or two before loading the next state. It's as though the nested view is lagging behind or something.
For example, after logging in, the login form is still visible for a second or two in the middle of the page after the state change. The parent view changes instantly, but that nested view just seems to stick.
I've been pretty careful about items on the watch list, and use one-time binding wherever possible.
But I really don't think it has to do with that, because this happens even early on in the application (from login to the main page), and other than this issue, application performance is fine.
I've googled a lot about this, but haven't turned up anything useful.
Any ideas on what to check or how to debug this?
You say it only happens the first time you transition after loading the app. So it could be you are injecting a service into the child view that you are using the first time in your app. This service is taking some time to instanciante. Servises are singletons, so this lag is only visible the first time.
Look at the answer in this thread for a possible solution, somebody had the exact some problem:
How to instantiate a service dynamically?.
Another solution might me to inject that service into the parent view as well, so you get the lag while loading the app not on first transition.
I am working on an ember.js (version 1.2) based mobile application and I am trying to find the most idiomatic way of implementing the global menu toggle/back button pattern that is common in many mobile apps. Specifically, its a button that sits on the left side of a fixed-top toolbar, which toggles a hidden drawer main menu when the user is at the app's home/index view, however upon moving into a sub route, the button displays a back arrow, and when clicked, it takes the user back to the previously viewed route (or back to the index route if there is no previous history states, i.e. if the user came into a sub route directly upon loading the app).
Fyi, currently I have my app structured with the fixed-top toolbar and menu toggle/back button in the root application template. Ideally this functionality would work no matter how a routes are being transitioned to, whether via transitionTo(), or {{#link-to}} helpers, ect.
So essentially I want to know if Ember internally maintains any sort of accessible history/log of what routes were transitioned to over the course of the app's lifetime, and also what would be the best way to conditionally change the action that the toggle/back button performs and its display (aka its icon) depending on the current route. And/or is there a way to listen to ember's route change events so I could implement that history myself if need be?
I hate to be the bearer of bad news, but I also hate to leave you hanging.
Ember doesn't keep track of the history, there isn't a general use case for it (especially since the browser keeps track of it for you).
Fortunately you can monitor route changes in the application controller, something like this should get you started (Note I didn't spend time working out an awesome solution that works perfectly, just showed you the basics you need for it, I'll let you figure out the workflow that works well for you)
http://emberjs.jsbin.com/IZAZemEP/1/edit
App.ApplicationController = Em.Controller.extend({
history: [],
hasHistory: function(){
return this.get('history.length')>1;
}.property('history.length'),
watchHistory: function(){
this.get('history').pushObject(this.get('currentPath'));
}.observes('currentPath'),
actions: {
goBack: function(){
// implement your own history popping that actually works ;)
if(this.get('hasHistory')){
this.get('history').popObject();
window.history.back();
this.get('history').popObject(); // get rid of route change here, don't need it
}
}
}
});
In a single page application, is there a way of switching back and forth to an AngularJS route and to display it back in the same state as it was shown before?
Usually this would be implemented by binding data in a parent scope. While this is easy to set up for lightweight view, it can be cumbersome when doing it for views holding lots of graphical elements.
Here is an example, where having the previous route state remembered could enhance user experience: on the following page, imagine that
you stand on Item 1 and select Tab 2
then move to Item 2
finally switch back to Item 1: Tab 2 is not selected anymore :-(
http://angular-route-segment.com/src/example/#/section1/1
It seems the views are destroyed/constructed when switching back and forth between routes.
A solution would be about storing the state of the user interface in a parent scope but it has the following pitfalls:
creating an object storing all the little details of the user interface
creating complex logic about -saving and- resetting the UI in the same state as before
storing UI state in a data model does not sound that MVC-ish
Using show/hide of div storing the views saves the state but then no route is used and the switching business must be implemented by hand. I like using routes because 1. of the browser history navigation (hash in the url) and 2. it is easy to set up.
Having the UI state not remembered is like having Chrome to reload pages when switching back and forth between tabs: not very user friendly.
Is there an Angular-way?
Your $routeSegment approach is very interesting. The $routeSegment service could plug into the $routeChangeStart event in order to
Somehow keep a "sub path history" on all paths seen so far, maybe only for those explicitly configured to keep their UI state. In your example for the path "/section1/1" the stored sub path would be "/Y" if tab 2 was selected. Things get interesting, as also dynamic paths with $routeParams might need to be covered.
Use this history for redirecting by using $location.path in the event handler. So a $routeChangeStart event with next.originalPath being "/section1/1" might be redirected to "/section/1/Y"