Reputation: 2449
~Disclaimer: this is an architecture question and contains traces of pseudocode.~
Assuming the following components:
<MapScreen>
<Map filters={filtersObject}/>
<MapFilters
filtersChanged={callback} //where callback returns a filters object
/>
</MapScreen>
And a filters object looking ~like
filters = [{
filterName: String
filterColor: String
}, ...]
There's a lot of ways to implement this but im more interested in the thinking behind which implementation to choose
A) Given that <Map Screen/>
doesnt need to be aware of the filters object in itself, is it desireable to pass the filters object from the callback somehow (e.g redux) directly to the <Map/>
object?
B) Yes <Map Screen/>
could hold the filter state but it doesnt do anything with it other than grabbing it and propagating it back down so it just feels like i'd be designing my seperation of concerns based on convenience..
C) Many people are in favor of the B) way. If so, then there's the question of, should then <Map Filters/>
only emit the filtersObject and receive it back in as a property instead of also storing it to it's own state thus avoiding having two states for the same thing?
I know the question here is very much up to personal taste but i'd love to hear your thoughts on this.
Many thanks.
Upvotes: 1
Views: 56
Reputation: 4078
A. Yes. If data need to be shared between components, redux or other data flow solutions is perfectly fine here.
B. If the data shared between Map
and MapFilter
is never used anywhere else or just inside MapScreen
and its children, then MapScreen
can hold the data in its state and pass as props to its children. This approach is commonly used since React components are designed to work for data flow between parent-child. However, you need to consider following trade-offs of this approach:
Since the data is shared by MapScreen
and its children, whenever data changes it will trigger MapScreen
along with all its children to re-render. Depending on the size of the data, how frequently data is updated and number of children of MapScreen
, approach B might be inferior in term of performance to approach A.
If you are dealing with animation in any children of MapScreen
, e.g. Map
and want to provide smooth and unnoticeable animation whenever data is updated, then it's very difficult to control since it is always forced to re-render along with the parental component MapScreen
. Of course you can use shouldComponentUpdate
to control re-rendering behaviour, but you have to put it in MapScreen
instead of putting directly in the children component. Then if you use approach A, MapScreen
will be a dumb component which is blind to whatever happens between its children.
C. Even without using redux, keeping only one single source of truth is important. MapScreen
should act as that source of truth by keeping data in its own state, passing state data as props to its children and listening to callbacks from its children to update state.
If you are absolutely fine with (B1) and (B2), then I highly recommend you to go for approach B, since pure React solution is usually clearer and faster than using add-in libraries. But if your data is still growing and you want to add more behaviours in the future, then go for A.
Upvotes: 1