How to be sure that the react-redux app is rendered based on the latest request? - reactjs

I have a react-redux application which:
Loads N records from the database depending on a "limit" query parameter (by default 20 records) on first application load (initialization)
Every 10 seconds app requests same (or newer) records from the database to update data in real time
If a user changes filters - app requests new records from the database according to the filter and re-renders app (+ changes interval to load data according to the filters)
If users scrolls down, the app automatically loads more records.
The problem is that if a user for and instance tries to filter something out and at this same time interval is loading more data, 2 requests can clash and overwrite each other. How in react-redux app I can be sure in a request sequence. Maybe there is a common approach on how to properly queue requests?
Thanks in advance!

I am not sure what you mean by 'clash'. My understanding is that the following will happen:
Assuming that both requests are successful, then data is retrieved for each of them, the redux state will be updated twice, and the component which renders the updated state will render twice (and the time passed between the two renders might be very short, which might not be very pleasant to the user)
If you want only one of these two requests to refresh the component, then a possible solution may be the following:
Each request starts, before retrieval of data from the database, by creating a 'RETRIEVAL_START' action. 'RETRIEVAL_START' will set a redux state variable 'retrievalInProgress'
If you want, in such a case, to get results only from the 1st of the two requests, you can check, before calling the action creator from the component, if 'retrievalInProgress' is on. If it is, don't call the action creator (in other words, do not request data when a request is in progress). 'retrievalInProgress' will be cleared upon successful or failed retrieval of data.
If you want to get results only from the 2nd of the two requests, then make 'retrievalInProgress' a counter, instead of a boolean. In the 'retrievalSuccess' action of the reducer, if this counter is higher than 1, it means that a new request already started. In this case, do not update the state, but decrement the counter.
I hope that this makes sense. I cannot be 100% sure that this works before I test it, which I am not going to do :), but this is the approach I would take.

Related

How to use the dynamic state in React.js, (from url)

If my data is coming from a url (xml or json) and from that data I have to set the state of my react component. The thing is that data is chaning every 5 to 10 seconds. Its data of traffic passing from a certain location where police thinks that people do over speeding alot. so I have to use that source for setting my state in react and display the cars registration number if speed is more than 100km. So data, (speed, time, registration number) of the vehicals i am getting from url online and it changes. So I want it dynamic, means when it changes, it should be updated in state too.
so should I have to make a call of initializing (componentDidMount) for exmple 500ms or something like it, and how?
I havent tried anything yet, cuz I am confused how to do it.

Updating async storage/data store in real time

I have a react native application where a user can edit a text which is stored in react state. I would like to implement autosaving so that user input is persisted in real time.
I have replaced my state with async persistence but have found that I am running into a race condition:
My parent component fetches the text from persistence.
The user inputs new text, which triggers a callback to update the given text with the new content.
If the user inputs text too quickly, before the persistence has updated and my parent component has fetched the new, updated text, the next async update is triggered on the old text, causing a conflict.
In particular, this happened with AWS DataStore. I have not tried using async storage, but given it also uses async/await I imagine I will run into the same problem.
A hacky approach would be updating at longer intervals but I'm assuming whatever interval I set will be long enough that each async update completes before the next. It's also more complicated as I have to keep local state which contains what the user sees while syncing that with the async storage/DataStore in the background.
Is there a nice way to replace react state with a persisted version that doesn't require a load of extra logic handling async race conditions? In an ideal world, some sort of usePersistedState hook which manages this all for me, exposing the exact same behaviour as useState?
To give an example of the race condition, say the text is a, and I type in b followed by c:
First DataStore update: a + b
(Expected second DataStore update ab + c)
Actual second DataStore update if input is too fast: a + c
DataStore result is some conflict, e.g. merging both updates to produce abac

Next.js - SWR hook question about dedupeInterval and refreshInterval

I'm using SWR hook along with next.js for the first time and i've tried to get some answers about something but i couln't get them, not even with the docs.
Questions: So, i know SWR provides a cache with your data, and it updates in real time, but i'm kinda lost between two options that you have to use the hook. So, normally, you have dedupeInterval and refreshInterval
refreshInterval = 0: polling interval (disabled by default)
dedupingInterval = 2000: dedupe requests with the same key in this time span
Now, what are the differences between these two ? if i have two request with the same key, it will update after two seconds ? is it the same as refreshInterval ? if i use refreshInterval, would i have problems with performance ? since it's making a request in very short periods of time
If you can help me with this, it would be great !
Thanks for your time !!
Now, what are the differences between these two ?
The difference is that:
refreshInterval is defining a time after which a new request will be sent to update your data. eg. every second.
dedupeInterval is defining a time during which if a request was already sent for a specific data (ie. a data having a specific key), when rendering a component that asks for a new request to refresh that data, the refresh will not be done.
Deduplicating means eliminating duplicates, ie. making potentially less requests, not more. They give an example in their documentation with a component that renders 5 times another component called <Avatar /> that uses the swr hook. But the actual request will be made only once because that rendering will be within the default 2 seconds time span.
If i have two request with the same key, it will update after two seconds ? Is it the same as refreshInterval ?
No, the dedupeInterval set to 2 seconds will not automatically update the data. It will update it only if a component using the same key with the swr hook is rerendered after the 2 seconds. Or if you haven't deactivated other updating mechanisms like on focus and the user puts the focus on your component.
With refreshInterval there would be an API call every X amount of time, as long as the component is still mounted, even if it doesn't rerender and the user doesn't interact with it.
If i use refreshInterval, would I have problems with performance ? Since it's making a request in very short periods of time.
Yes, if the user opens your page and does nothing but reading content during 20 seconds, and you have set the refreshInterval to 1 second, there will be 20 API calls to update that data during that time. That behavior may be useful if your data changes every few seconds and you need to have the UI up to date. But clearly it can be a performance issue.
The reason why the refreshInterval is disabled by default whereas the dedupeInterval is set to 2 seconds is to avoid too many API calls.

Best way to refresh token every hour?

I am building a website with React and I have to send about 3 requests per every page, but first of all I have to get communication token that needs to be refreshed every hour by the way, and then use it as a base for all other requests.
I have a plan to get it as soon as App mounts and put it in state (redux, thunk) and use it in every component that subscribes to store and then put setInterval function in componentDidMount method too. Another thing that comes to my mind is to put it in local storage but that would be a bit complicated (I have to parse every time I get something from local storage).
class App extends React.Component {
componentDidMount() {
this.props.getToken()
setInterval (this.props.getToken, 5000)
}
This works pretty well, and switching between pages doesn't spoil anything, it works pretty good. Note that here 5000 miliseconds is just for trying out, I will put it to be 3500000. Is this OK or there is another way to do this? Thanks!
Your implementation is pretty fine although I'd make a few changes
Use local storage so you don't have to refetch your token if user refreshes the page (since it'll be lost from memory). Also you'll have same benefit when working with multiple tabs. You can easily create some LocalStorageService that does all parsing/stringify for you so you don't have to worry.
I'd suggest to move that logic to some kind of service where you'll control your token flow much easier - e.g. what happens if user logs out or somehow token becomes invalid? You'd have to get new token from other place than your App (since root componentDidMount will be called only once) and also you'd need to clear the current interval (on which you won't have reference with current implementation) to avoid multiple intervals.
Instead of intervals maybe you could even use setTimeout to avoid having multiple intervals in edge cases:
getToken() {
// do your logic
clearTimeout(this.tokenExpire);
this.tokenExpire = setTimeout(() => getToken(), 5000);
}
Overall your implementation is fine - it can only be improved for easier maintenance and you'll need to cover some edge cases (at least ones mentioned above).
Ideally your server should put tokens on secured sessions so they are not vulberable to XSS.
If there's no such an option. I'd suggest using axios. You configure it to check the tokens on each request or response and handle the tokens accordingly.

Adobe Flex Caching Array

My program fills an array with data from a facebook page feed but every time i go from one tab to another it wants to reload this data, is there any way i can cache this array so that it will not reload the information unless its changed?
This is exactly why your Views should not contain Service logic. Instead, your View should dispatch an event asking for the service call and your Controller (you do have one, right?) should catch that event and decide whether to act on it or not.
How do you know the data hasn't changed without reloading it?
Maybe what you need is to store the timestamp of the last service call, than measure the amount of time before executing the service call again.
Perhaps with a 5-minute timeout, if the user continuously changes tabs within 5-minutes from the last service call, the array persists previously loaded data.
After 5-minutes, if the user changes back to that tab the service call can fire, load data, than update the timestamp to prevent loading.

Resources