I am building a web app using React (15.3.0), Redux (3.5.2) and react-router (2.6.1). I include the versions as I've seen a few related posts but they reference old versions of these libraries.
I have some state that I would like to persist on the URL so that the user can deep link to it. By deep linking, I mean that a user can link directly to a state of a page. I have various pages in my app, each page has a separate reducer, the state for each page should persist between pages.
I've read Dan Abramov's recommended approach: How to sync Redux state and url hash tag params
Which seems ok, apart from persisting state between pages.
An example scenario:
User lands on page one: /page1
User interacts with the page causing state to be saved in the URL: /page1?state={...}
User goes to page 2: /page2
User interacts with page 2: /page2?state={...}
User links to page 1, expecting to see that page as they left it. Problem! How do we recover the state from page 1?
I've looked at react-router-redux, but I can't tell if it does what I need it to?
Is there a common approach to this problem? If so what is it? If not, can you suggest an approach?
I'm sure there is more than one answer to this; you just need to pick one and implement it.
If it were me, I would do this:
Use the redux store as the single source of truth for state
Subscribe to the store in some way (perhaps a redux middleware) and update the url params when the relevant state for page1 changes
If a user visits /page1, use the stored state (I'm assuming state will need to be synced to a server to be able to store/recover it).
If a user visits /page1?state={...}, either a) merge the URL state into the stored/recovered state or b) skip recovering and use the URL directly.
I would even go further and NOT sync the state to the url, since that seems like wasted effort (unless users are relying on bookmarking a page). Just render a React component saying "Share this URL" and have it render a URL with proper query params.
Related
I'm working on a Next.js application with a Firebase backend and I have the following set up: a user can create a session that other people can join, but only the creator can "start" the session (trigger a state change). When this stage change occurs, I want to refresh the browsers of all users in this session.
When a user creates a session, they are redirected to pages/[sessionId] and a new session is created in Firebase (real-time DB). My pages/[sessionId] has a switch statement that looks at the state of the session ID (whether it has been started or not) and it displays a component based on this.
Here is what I've considered so far:
I could technically use the useRouter hook and reload the page, but that would only reload the page for one user who triggered this change, whereas I want to do this for everyone.
My next thought was Firebase cloud functions to somehow trigger a state change signal, but Firebase has no idea who is connected to my session
Then I thought that Next.js comes with Server-Side-Rendering (even though I understand that SSR isn't meant to provide backend functionality), so perhaps there could be a way to accomplish it with pure Next.js, but I've got no idea how
Many thanks in advance!
I figured it out on my own, it turned out to be quite simple. For anyone else who might be stuck, here is what I did: inside of my useEffect, I have a function that fetches the current session state and then inside a then clause, I have another function that makes use of the onValue function from Firebase, so as soon as the state changes, it triggers another function call that is performed for all users.
I am currently using UniversalRouter for routing in a react application that contains a form and other UI elements to allow users with admin permissions to make changes to data within the app for other users to see. I would like to be able to detect when a user is about to leave the page so that I can display a warning and give the user a choice to save their changes or abandon them.
I have seen other results that seem to address this problem for React-Router, but I have yet to find any results for achieving this using UniversalRouter.
In looking back at one of the blog posts where I discovered UniversalRouter, it seems like this would be something that I would need to implement by communicating with redux (i.e. by subscribing to state changes) rather than through the router directly.
I'll keep looking into this and self-answer if I get something working, but I would be very interested to know if anyone else has already implemented this 'warn the user about unsaved changes when they're about to leave the page' functionality in an app that uses UniversalRouter.
I created a shopping website in reactjs where I have divided the app.js file in to header ,routes and footer.the router is by default redirected to welcome page.But after I login I am redirecting my page to the same welcome page.but then I am not able to update my header with user name and logout by updating the existing nav.i know it is because of the fact that the header is not getting rerendered.But can some one help me to some how make it rerender?
You shoud use redux.
Redux is a predictable state container for JavaScript apps.
It helps you write applications that behave consistently, run in
different environments (client, server, and native), and are easy to
test. On top of that, it provides a great developer experience, such
as live code editing combined with a time traveling debugger.
You can use Redux together with React, or with any other view library.
It is tiny (2kB, including dependencies).
There are many topics about redux.
there is a function called: mapStateToProps.
suppose you have a action (login,logout,addToCart,removeToCart etc.) at A component.
You want to B and C listen to your actions. for example when user do logout, you want to remove username of your header. at this here redux helps you!
I am writing a react-redux application, that has some 4 routes. I am using react-router to navigate to different routes. My question here is, is it recommended to delete redux state on navigating to a different route?
In general I would not say it is needed to delete existing state when transitioning to another route in the app. If you come back to that part, you can display data faster. You might need to consider if there is a need to refresh that when you come back to it.
As other's here said, there is no reason to delete state from redux, even if you're not using it in the current route.
You said that you're loading your state on componentDidMount. Do you want to reload server data every time a route is switched? Because if not, you can add a condition to your componentDidMount to only re-load the data from the server if it hasn't been loaded yet.
I have graph with data in welcome page like widget(/welcome). when the user clicks the graph the page change to /home/default and the same graph should be displayed along with some extra data which is populated by Ajax call. What I want is to persist the graph data from /welcome into /home/default page. I don't want the data to go controller and back to the /home/default page. Kindly suggest.
In a nutshell, you need to set some state for the user and then when the /home/default page is rendered, you need to check that state and make corresponding changes to the presentation of the page.
This can be done either server-side (in the rendering of the page) or client-side (via Javascript adding things to the page).
If you do this client-side, then the state can be stored in a cookie, in LocalStorage or in a query parameter in the URL when you redirect. Then, you place Javascript code into /home/default that checks that state and adds content to the page dynamically based on the state.
If you do this server-side, then the state can be stored in a cookie or in some server-side data store and then when the /hoome/default page is rendered, your server side page rendering process can check the state for this particular user and modify the rendering of the page to include the desired content.
You have a plethora of options. The best solution depends on how your application is currently implemented -- whether in a framework or not, with sessions or not, etc. The principle whatever method you choose is almost identical: store a value and then retrieve it later.
Single Page Application (SPA)
If you aren't already using a framework, I would urge you to consider migrating to one as tasks like these are made infinitely more elegant in their implementation.
Service / Data Store
If you are building an SPA then you may not have to consider any of the options below... so long as it doesn't matter if the data is lost if the user performs a 'real' navigation that cannot be intercepted by the framework (for example, refreshing the page).
In Angular you can maintain a temporary data store in the form of a service. Simply store the data and then pick it up later from another controller. Similar functionality can be achieved in all other popular SPA frameworks:
Angular
Ember
React
Local Storage
Local Storage is available in IE8 and above and has a really simple API.
Angular: angular-local-storage
React: react-local-storage
Ember: ember-local-storage-adapter
jQuery: jStorage
IndexedDB
If you're into the cutting edge and aren't tied down by browser support, consider using IndexedDB. I don't recommend using this unless you are wanting to persist large amounts of data remotely on the client's machine. (It really does have bad support at the moment.)
Angular: angular-indexed-db
React: ???
Ember: ember-indexeddb-adapter
jQuery: jquery-indexeddb
Cookies
If your application is inflexible then cookies will be the easiest and least time-consuming. However Local Storage may be a contender.
Angular: $cookie service
React: react-cookie
Ember: ???
jQuery: jquery-cookie