Extract React Router state in URL - javascript

I'm using react-router and redux-simple-router in conjunction with server side rendering and when I navigate to a url like:
routeActions.push({ pathname: '/main', state: 'some_state'});
I want to be able to extract some_state from the request so I can render an initial redux state and send that back to the client. How do I extract the state from the request on the server side? Where does history and react-router put it?
This is particularly important for mobile because desktop, as I've tested, doesn't fire separate requests but mobile devices do which means the page reloads with a fresh initial state.

state corresponds to state in the History API - it's associated with the current location, but it's only available on the client, so it's not suitable for passing along arbitrary data if your app needs to support server-side rendering.
If you want it to be available on the server, you would need to make it part of the URL. perhaps as a query string.
Aside: location state is useful in other ways in isomorphic/universal apps, such as passing around POSTed form data to be handled using an onEnter hook, or for passing form data and validation errors to use a redirect transition to respond by rendering an invalid form in the same scenario.

Related

Avoid duplicate REST calls due to URL Navigation

My application is based on AngularJS 1.8 and angular-ui-router. On Successful login of the user, application is navigating user to a particular URL location by doing:
$window.location.href = "../"; //Let's call it Navigation-1
Now based on user type, the application adds query parameters to the URL, and causes another URL navigation
/?user=admin //Let's call it Navigation-2
These Navigations causes the states to retrigger (twice in this case), thus sending duplicate REST calls to the server.
My question is How do I avoid duplicate REST calls? I tried to capture events such as 'load' etc. but it doesn't work.

Routing to different pages based on a condition

So we are creating different pages for our application and we need to route from one page to another everytime. We are working on Next.js.
Problem - Say, we have a Home page. From this home page, we can either route to pageA, and the pageA will show different data or different form based on the query parameter passed in the routing, and we need to keep passing that query parameter to upcoming pages to maintain that journey.
Now, as I can see, the usage of query parameter is getting a bit complicated as the application is growing.
I would like to know if there is any other way to do routing where we can skip the usage of query parameter and still maintain the state.
If the query parameter is sent to many subpages, you can use localstorage (or sessionstorage). On the page mounting, you can get the values inside localstorage and set them on the hydration phase.
Using localstorage is as safe as query params. With localstorage, it will be easier for you to send values to sub-routes. If you only have one or two sub-routes, query params are ok but with more sub-routes, the code logic / maintainability could be annoying (especially because you want to always send the same query params to sub routes). With localstorage, you can also create a custom hook to get the values / update the value into multiple components.
Just as a reminder, don't store any sensitive data inside localstorage. I recommend you to read the new Next.js routing system too ! (breaking changes) Read it here.

When using react-router, I refresh and lose my state?

I'm passing previously fetched data, through location.state to subsequent components. That works fine, however, if the user hits refresh my history, and location state objects are wiped out. I can see that this is the intended functionality. My question is, am I supposed to be using redux to keep this data persisting? If that's the case, I lose a lot of the benefits of react-router in my opinion. How are people handling state when using react-router?
You can pass the states as props, or save it in localStorage for a wider access.
To be able to persist the data, you should store your data on database or localstorage for an example. And when you refresh the page, you can fetch your data from the store.
If your component is class base component you can use componentDidMount for fetching the data and set the state or redux.
If your component is functional component you can use useEffect for the same scenario.( react version should be greater than 16.8)
https://reactjs.org/docs/react-component.html#componentdidmount
https://reactjs.org/docs/hooks-effect.html
Data can be stored locally on the browser with the localStorage() function. The data can also be sent to the next component by using the this.props.history.push function.
In the end, I chose to save the data in the browser's local storage as I wanted to pass and access the data in a child react component and being able to refresh the page. By saving the data in the local storage the data stay whereas any using the history.push() functionality to pass the data, the data is deleted after hitting the refresh button.
Below there is an example in case you want to pass the content of the pseudo variable in the child component.
localStorage.setItem('pseudo', this.state.pseudo)
OR
this.props.history.push({
pathname: '/NextPage',
data: { pseudo: this.state.pseudo }
});
To get the data in the child component NextPage.js you can use the following code:
props.location.data.pseudo
OR
localStorage.getItem("pseudo")
React-router isn't concerned with state management. To manage state, use Redux or other solutions like Xstate. To persist data on the client you may look at localStorage

hashbang #! url patterns for REST on the client side

I've a single page application with my own custom router.
window.onhashchange = function(event) {...
and I've hash bangs like following.
#!/products
#!/products/1
#!/brands
#!/brands/1
But they seem to emphasize GET requests, I'm listening to URL changes and is there a REST based convention clean URL's based on industry standard, perhaps used by angular, React etc. to indicate a POST request or DELETE request.
So router can dispatch a respective call accordingly.
hashbang urls are not meant to indicate any REST based remote calls, instead it's used to define to state of a SPA page it's currently in. State means the kind of content that's visible for the specific hash bang url.
for instance for #!/products display product related forms, controls and associated content and vice versa for #!/brands.
It's the user actions on the associated content that the developer needs to interpret and translate them into REST specific calls.

How to load initial store data through meta tag before redux sagas are complete?

Currently, I'm running into a situation where a server rendered page is loaded prior to sagas completing which populate the store. However, elements such as links are dependent on the store in order to fire an action. e.g. login link would need to change that state of the application to show a modal, but doesn't have access to the store data yet. I would like to load the initial store immediately through a meta tag. How can I achieve this?
It's not clear what you actually need. If i understand you right, you just need to wait when all sagas are done then render markup on the server. You can achieve this by wrapping server side sagas in saga-wrapper and then run it through middleware API:
sagaMiddleware.run().done.then(...) <- regular Promise

Categories