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.
Related
I have the following problem:
I have a document with data in firestore. I collect the data from that document and show it on the screen, everything is perfect. But, if I add data or modify it, how can I get the new data at the moment the document has been updated, without continuously checking if there have been changes? Since it would exceed the firestore reading limit. That is, it receives a kind of notification that there is new data, checks it and updates itself. I've tried with a state variable(useState) inside a useEffect but I can't find a way to make it work.
I hope you can help me.
first at all try to make a get right after your create or update action on the document.
If you don't want to do that, you can read this part of the documentation of firestore and try to create a custom hook calling it directly on the useEffect (in order to get every update in the lifecycle).
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.
For my client I'm creating something like quiz web app in react with redux based on websockets (socket.io) with a huge, very unique data. No user interaction, just presentation layer. It works like this: I get websocket event with url to my layout and payload data, and then I render given url and fire redux action with data as argument, which becomes app's state. Simple as that. BUT I noticed that on first render initial state is loading, not given from websocket as argument to action. As I said data I get is huge and unique so I didn't want declare in reducer something like this:
pageData: {
assets: [],
questions: [],
details: []
And so on. It's much more complicated btw it's just an example. Instead of this I made something like this:
pageData: {}
And I was hoping that on view (using connect) I can get this data like this:
this.props.view.pageData.questions
But then it turned out that I can not get this because it's undefined on first render. So my questions are:
Is there a way to access to this data on first render without
declaring whole structure?
If not, should I reconstruct given data in reducer?
Should I then create reducers for each page (there are like over 20 views
with unique data)
Of course I can declare everything in reducers but I feel it's very hard to maintain so much data.
But you know, maybe I'm just too lazy and I should declare initial state for each page and this question does not have sense ;).
I think you may have a few options here:
Define fallback data in your components if undefined
Don't render your page (or components) until you have received the data
Define your initialState explicitly as you already suggested
All or most your components expect or should expect data of a certain kind and in a certain format. For this reason, laying out the structure beforehand (#3) seems to be most appropriate. Ask yourself this: would my app still display correctly if the format of the web socket event data changes?
To answer your questions specifically:
Is there a way to access to this data on first render without
declaring whole structure?
Yes, you could use the || operator in your bindings to fall back (#1) to an empty array or object or value. Example <MyComponent listOfItems={this.props.items || []}. This effectively creates an empty state, however, IMO this should be standardized in the reducer/store with initialState.
Should I then create reducers for each page[?]
Not necessarily a reducer for each page, but a store with all pertinent data to your application. It is hard to say for sure without knowing more about the architecture of your app, but keeping small, well defined chunks of information is generally easier than one big blob.
I strongly advocate defining your data beforehand. It might sound cumbersome at first, but it will pay off greatly and helps others understand what the app might look like with live data.
that's because you haven't added default case in reducer
default:
return state;
I have an application which receives messages from a server every 1 second and via socket.io these messages are broadcast to a react component.
My react component is using a flux style architecture, so it calls an action when a message is received which adds (or updates) a record in a collection in a store.
My component monitors changes on the store and then updates the UI when it changes. In this case, it draws a marker on a map.
The problem is that due to the frequency of the updates my component redraws all markers every second, which I don't want.
I'm looking for an approach to allow my map component to respond to changes in a collection in a store, but not have the state update every second.
I thought I could have a collection for the raw data, and then only update the networkGPS collection selectively in my store, but the component seems to change based on any property in the store as they all seem to be part of its state.
In summary I'm looking to:
Collect data every 1 second in raw form and add this data to a store.
Bind a component to a collection in this store which I update only when changes require a UI redraw.
What I think I need to do:
Either:
Avoid putting the raw data into the state of the store (at the moment I'm unsure how to declare a collection which is not part of the state)
OR
Make my component more clever as to when it redraws, so it doesn't try to redraw on each state change.
I'm not sure which is the most appropriate solution for the problem, any info would be gratefully receieved.
Sorry if the question is a little unclear, I'm new to react / flux. Please do ask for any clarifications.
EDIT
At the moment I am getting round this issue by storing an array of the items (map markers in this example) I want my component to display in the component itself :(
When the state changes and render is called, I intercept the state properties, decide if anything needs to change in the collection of markers and only amend them if needed. If no changes are needed, the collection in the component stays the same and no redraw is performed.
This is not ideal, I feel like I should be able to allow my component to respond to only specific state changes but I've not found it yet, still looking for a better answer.
There are a couple of ways to approach this:
1) Use shouldComponentUpdate to compare old props and new props, re-rendering only the new marker states.
2) Switch to a cursor-based state tree that automatically triggers renders only for views that are bound to the specific parts of the state tree that have changed. I believe Baobab is one such library. See also Om (written in ClojureScript) and probably a number of other Flux implementations.
Given the impact of #2 my vote would be to go the route of #1.
I am not quite sure what's the problem that you face with updates every second.
However, the one place where you can queue the updates is between the socket.io and calling the action.
Instead of calling the action every second, you could queue the updates before sending it across to react.
Imagine the following:
you're writing a 'smart-house' application which manages a temperature in your house.
In my view I'd like to:
see current temperature for each room
set desired temperature for each room
see whether air conditioning is turned on/off for each room
There is an external device, communicating with your aplication via websockets (it is periodically sending current temperature, air conditioning status).
I see two options there:
1) Create one 'big' store containging data structures like:
var _data = [
name: 'Kitchen',
currentTemperature: 25,
desiredTemperature: 22,
sensors: [
{
name: 'Air Conditioning'
state: 'on'
}
... there might be other sensors too ...
]
]
There will be a TemperatureManager component (or something similar). It would have a state and fetch it from Store periodically.
Then it would just distribute part of the state to his descendants (ie RoomTemperatureManager, RoomSystemSensorManager), passing it as props.
If anything changes (for example, temperature in the bedroom), it will fetch all data from store and re-render its descendants if necessary.
2) The second solution is
to make RoomTemperatureManagers and RoomSystemSensorManagers have their own state. It is also related to having standalone stores for both Temperature and SystemSensorState.
Those Stores would then have parametrized getters (ie getSensorState(roomName)) instead of methods to fetch all data.
Question:
Which option is better?
Additional question:
Is it okay for leaf components (ie the one responsible for managing desired temperature) to call ActionCreator directly? Or maybe only the Supervising Component should know anything about ActionCreator and should pass proper method as a property to his descendants?
The 2 options you describe in your post are really 2 diffent questions:
One big store or several different stores?
Should child components (RoomTemperatureManagers) have their own state or receive props from store?
Ad 1. One big store is easier, as long as it does not get to complicated. Rule of thumb that I use: if your store has > 300 lines of code, probably better to separate in different stores.
Ad 2. Props are generally better than state. But in your case, I would think you will need state in e.g. your Temperature-manager: you set the temperature in your app (and want to see that reflected in some slider or whatever). For this, you will need state.
State updates the front-end immediately (optimistic update).
The component then sends of a set_temparature action to a sensor in the
house.
Then the sensor in the house confirms that it has set the new
temperature to your app.
The store(s) update(s) and emit change.
The temperature setting from the sensor in the house is communicated as
props to your Temperature manager.
The Temperature manager does whatever it needs to do (simply update state with new prop, display confirmation message, or nice error message if things broke down along the communication chain).
I believe the best approach would be to delegate. Your TemperatureManager should have a mechanism to notify listeners that there is an update and in turn, the Room(Temperature|System)Manager would send as a listener a callback that would consume the updated data and change the state accordingly. This will leverage the virtual DOM diff so only changes will be displayed and not whole parts re-rendered as well as create a single point that would communicate with the Store. Room(Temperature|System)Manager should only communicate with the Store if there is an update it needs to do to the model it is working with.
TemperatureManager could be improved if on subscribing, you can specify which data to listen to for updates. It should not assume that a particular 'manager' should get any subset of data.