Should the Redux state tree represent how the data is organized in the user interface?

Situation

I have a React / Redux application that displays markers on a map and groups them into clusters based on their proximity, given the current zoom level ( similar to this example - my application is slightly different from this example in that clusters on the map will display certain data from their child tokens, not just the total number of child tokens).

I assume that new markers are added frequently and the application will be updated to show new markers in real time.

The structure of the React components looks something like this:

<Map> <Cluster markerIds=[...] /> ... </Map> 

Thus, the map re-displays the corresponding clusters each time a) new markers are added to the map, and b) the scale of the map changes.

I am trying to determine the best way to organize this data in a Redux state tree.

Option 1: a simple approach

One option is to keep the state tree very simple and let the UI process all of the clustering logic as needed:

 { markers: { 1: { name: 'Bob', location: [-40.08, 37.62] }, 2: { name: 'Steve', location: [51.08, -25.62] }, ... } } 

If I organize the state this way, the user interface will have to go through each marker and recount the visible clusters every time the zoom level changes. With a lot of markers, this can turn out to be a lot of recalculations, and I expect users to do a lot of increase and decrease when using this application.

Option 2: Store Cluster Groups for Each Scale Level

Another option would be to save the cluster organization in the state tree for each zoom level (for example, from 1 to 19):

 { markers: { 1: { name: 'Bob', location: [-40.08, 37.62] }, 2: { name: 'Steve', location: [51.08, -25.62] }, ... }, clustersByZoomLevel: { 1: { clusters: [ { clusterLocation: [22.59, -21.54], markers: [2, 11, 4] }, ... ] }, ...2-19: {...} } } 

In this case, cluster calculations will occur only when new markers are added to the map and will only be performed on new markers, and not on the entire set. Scaling or shutting down does not require recalculation, since the cluster organization will already be saved in state.

Question

So which option makes sense?

On the one hand, I have to keep it simple and avoid premature optimization (i.e., go with Option 1).

On the other hand, I see that Option 1 can easily lead to tons of recalculations occurring very often. Option 2 provides a state tree that is more directly converted to my React component structure.

Which option would you suggest and why? Are their other approaches that I am not considering working better?

+5
source share
1 answer

From what you ask, they are both viable.

Due to the nature of your exact question (depending on scale), I would say that the caching layer is completely viable (as long as a clean dataset remains there).

In terms of the abstract set of thoughts that my team works: if it can be trivially obtained, do it in a transformer, which is supplied to connect( transform, bind )( Widget ); .

If it cannot be trivially obtained, caching it makes a lot of sense.

Great examples of this are where you can have 8000 results of unprocessed products, and then a filter slider that works on all kinds of data as a result.
You will want to keep a list of filtered results so that you don’t have to constantly recount it on the fly.

However, to change the page number in the view, it is not necessary to restart all these expensive operations with the filter (i.e., in the conversion), but simply choose which subset of the view has been sliced ​​from the list of all already filtered results.

This is one step further than what you are asking for, but my other suggestion would be to "organize using the interface": be careful that you rotate the general data from the "branch" or "api" of specific branches of the tree and move them to ordinary place if they are really common things.

To mutate an object in two different places, synchronizing with each other would be painful.

 { searchPage: { user }, landingPage: { user }, checkoutPage: { user } } 

According to the user interface, this will be very painful.

So ... transform what you can use, you can cache what you cannot, rotate what is usually close to the root.

+4
source

Source: https://habr.com/ru/post/1244971/


All Articles