setState Before Route Change - javascript

I have an authentication state that I use through the Provider/Consumer context API in React 16.
I initially set the state of this property in my main App to false and then for any restricted components (i.e. that require being authenticated) I make a query to the backend to check if the current token on the client-side is valid.
Thus, I want authentication to always be consumed as false initially by any components when users change browser URLs.
How can I reset authentication on each route change? I am listening on history.listen but if I call setState there is no guarantee that authentication will get set to the false state before the component initially renders.

Related

How to make multiple api end point calls in sequential order with react redux javascript?

I have a redux store containing multiple states which is populated by same api but multiple end-points.
I have a react app with multiple components, which access to one of these states, and they all call to the correspondent api no mount by dispatching a async function (redux-thunk) to the store.
In the App.js multiple components are used.
Problem:
When all the components mount they call to the api concurrently and exceeds the maximum number of call allowed for the short time frame. Thus all calls reply with status code 429: Too many request.
*Extra notes: I'm buliding a news web-app, and using gnews.io api with multiple search queries and end-points to get data.
In your case i believe one approach would be to create a request type and use it in your state instead of the raw value returned from the endpoint, something like:
type TApiRequestState<T> = {pending: boolean, response: T}
When you dispatch an action that will trigger the endpoint in thunks you would set the api state to loading.
After that all you need to do is check if the request is not already running on the other components.
if (!value.pending && !value.response) {
dispatch(thunksFn)
}
In theory you could dispatch all of the initial requests on a parent component and only render these child components when the initial requests are done. But this depends on a project to project basis IMO.

Vue-Router global function execution on route change

So my query is that is there a way to get Vue-Router to execute a function/method after route changes? More specifically, after the route has been mounted successfully.
Currently, I do loading function that evaluated to true once the user clicks away from the initial screen. And each page has a mounted function (repeated across all my vue pages) that sets the loading to false.
I want to have it such that the router detects this change, sees if the new routed component has been mounted and then executes a function to set the loading to false.
I use a dedicated router.js file to contain all my routes and params for it and then call that file in the main app.js file that mounts the view for the user.

Component makes a GET request on mounted() and props response to child component. What happens if I type URL that goes straight to child component?

So imagine I have these 2 URLs:
example.com/Profile
example.com/Profile/City
When example.com/Profile is visited, I present component Profile and when example.com/Profile/City is visited, I present component City.
I need to make a GET request that returns information used in both components. Currently, I make that GET request in the mounted() lifecycle hook of both components but I have been wondering if I can do it once only in the parent Profile component and then just props it down to City so that I could get rid of 1 GET request.
However, I am not sure what would happen if a user straight up types example.com/Profile/City? Considering the GET request is executed on mounted() of the Profile component and we haven't mounted Profile since the user straight up typed the URL that leads to City component , will I have the response in the child component?
Considering the GET request is executed on mounted() of the Profile component and we haven't mounted Profile since the user straight up typed the URL that leads to City component , will I have the response in the child component?
No, you won't. You will end up with no data.
I have been wondering if I can do it once only in the parent Profile component and then just props it down to City so that I could get rid of 1 GET request.
Not really. However if you used a global state management solution like vuex, you could move the request and the data into this global state and trigger the vuex action for the request from both component's mounted.
Then you could implement logic in your vuex action that would skip the request if the data is already present (i.e. from having previously visited /profile). But in that case you should make sure to save some timestamp so you don't cache the data indefinitely.
If you expect the data to change frequently, I wouldn't cache it like that at all and rather do a duplicate request everytime to ensure the data is a fresh as possible.

LocalStorage with react-redux

I'm using React and Redux for my SPA and I want to store some data locally. And I need to synchronize appState with localstorage, so my data won't be lost after refreshing the page.
I'm completely new for React and Redux and have not much of understanding what's going on, but as I think Redux creates for me that state of entire app, so I can't just bind my state with localstorage in app component because it'll be just state of component and not of my app.
I would suggest storing the data in local storage with the following commands.
Set the data in localStorage can be done with the command:
localStorage.setItem('nameForData', variableNameForData);
To retrieve the data when required.
var variableNameForData = localStorage.getItem('nameForData')
To remove the data from localStorage:
localStorage.removeItem('nameForData')
These would typically be put inside action creators with a dispatch to change the state of some Boolean that tracks the applications interaction with localStorage.
For example you might have a state that is set to true when the local storage is created.
On refresh you might call an action creator that checks the local storage exists, and if it does set that boolean back to true or if it does not exist you are back to creating local storage and then set it to true.
You could put this function in componentWillMount(){} and it will be called when the component is first rendered, and thus in the case of a refresh.
Docs for component life cycle and specifically componentWillMount here
Docs for local storage here
I can suggest you to store the state after each action. For that you can use a localStorage middleware that only store the whole state object.
Then in your createStore part you will retrieve the initialState from the localStorage API.
In that case you don't need to modify any component, juste the initialState from localStorage and the middleware that save the state

Pass Props Between Routes Using React-Router

Is the only way to pass data between routes in React-Router (1.0.0-rc) url params? I have a component, A, which uses the History mixin, and has an event handler that makes a server request and then calls that.history.pushState(null, '/B'); to transition to route B handled by component B.
Now, I would like to pass some of the data I am returned by the server to component B as a prop (e.g. "login successful"), or somehow affect the state of B, but I can't find any documentation stating this is possible. Is there any way to do this, or do I need to pass it as a url parameter?
You have two options:
pass the data as a query params
keep the state of the application somewhere else, outside of the routes
For #2 you could use something like redux which will keep a 'global' store of the application state. You can then access this state from both component A and B.
Use localstorage or sessionsessionstorage. Set data in first router, get it on second router using set and get item of localstorage
https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

Categories