How better organize React-components interactions?
I am building SPA with React and have the following structure of UI-components:
- App (base layout with navbars and footers)
- EventsIndex (Load Events data from API)
- FilterBar (common components where current filter settings is shown)
- EventsTable (show Events data for desktop)
- EventsAccordion (show Events data for mobiles)
- EventsIndex (Load Events data from API)
EventsTable and EventsAccordion have a lot of common logic such as pagination, filter's and sorting's handlers.
I have to lift up handlers from child components(EventsTable and EventsAccordion) to parent EventsIndex. But for me it seems not the best way.
Am i wrong?
What the best practice in such cases?
Should i use Redux? If no, when it better to use it?
You can follow a container type implementation - which means that if there is some common logic between components, they can be encapsulated within a component that acts as a container for these two components and provides the necessary common logic / data.
So, for example in your case it'll be something on the lines of
- EventsIndex (Load Events data from API) - FilterBar (common components where current filter settings is shown) - EventContainer (where common logic resides for both your components) - EventsTable (show Events data for desktop) - EventsAccordion (show Events data for mobiles)
EventContainerprovides the common props such as pagination, filter's and sorting's handlers.
Hope this helps :)
The best approach that we follow in a team setting (and is opinionated; and probably won't fit in everyone's scenario) is to break the app into logical structures.
- src - Utils (reusable methods such as sorting, pagination, etc) - UI (Reusable UI components such as buttons, modals, etc) - Services (API Calls to the database, further divided by entities /users /posts etc) - Components (Hierarchy of components) - EventsIndex (uses the service directory to make API calls) - EventsIndexContainer (if following container encapsulation pattern) - EventsTable - EventsAccordion
If the handler isn't component specific, I'd suggest move it to the utils folder (so that you have a single responsibility pattern as well as a single place to modify your logic rather than in two places) and pass down the handler to the table and accordion from the EventsIndex component or a EventsIndexContainer component that further encapsulates your logical components (the later one is preferred my many who I've worked with).
React is all about Components, I would say the most important part when starting to design a React App is structuring your Components well.
There are different ways to structure your components well, below are some:
Container Components: When designing your app identify the container components, these are the components which are going to hold state and also manipulate them based on events.
Coming to your question: I have to lift up handlers from child components(EventsTable and EventsAccordion) to parent EventsIndex. But for me, it seems not the best way. Should I use Redux?
Answer: When using container components only a few components are going to deal with the state and any child hierarchy ( Child Components ) are going to be stateless components / ( Functional Components ), so in order to update the state they will have to have handlers passed down by their Container Components, using which these components are going to update state. ( This is absolutely fine, that's the way it should be )
Coming to REDUX, using REDUX in such small scenario is not recommended, I would not recommend it, because it would be an overkill, REDUX is apt in a much complex scenario when you would like to share some state between two component trees, but still you could use REDUX but its just that, its not recommended.
HOC ( Higher Order Components ): Whenever you have some functionality which is reusable, consider creating a HOC
Please check : HOC
Break Components to Smaller Re-useable pieces: This is often very important whenever you see that a component contains code which is used elsewhere, go ahead and make it a Separate Component, thus making it Reusable.
Please check this, this has a bunch of best practices https://www.toptal.com/react/tips-and-practices
When to use REDUX ?
Basically, you need to be using REDUX, when keeping the state in a top-level root component is no longer sufficient, like for example : ( you have two branches out from root component, one of the child component in branch A wants to access some state in branch B's child, then you need to move it to the root component and again pass it down, such cases are apt for REDUX ).
Please check this source: https://redux.js.org/faq/general#when-should-i-use-redux