What is best practice for handling data in React components? - reactjs

Currently I have my parent components handling all my Axios calls, and I'll pass that data down with props. Should my child components be handling those requests individually in each child component, what is the best practice?

Should my child components be handling those requests individually in each child component, what is the best practice
There is no such rule which says that parent component should get all necessary data and pass that data down to all child components through props.
We can imagine a situation where we have top panel element which shows:
person name
weather temperature
current date
Yeah, if we make requests from each component, then we will have three API calls. So far so good. But on the next day, client says that he wants to show weather temperature in bottom panel. So we will have weather temperature at the top and bottom panel. It means that we will make 4 API calls. And it is not good solution.
What we can do? So if you are going to need to share the state across a lot of components then we could use state management library or useContext hook (it is simpler and easier to understand than Redux). Both have pros and cons.
If your application is not small, we can use state management libraries such as Redux, MobX, Zustand. However, it is completely okay not to use state management library if your application is not big.
Do You Really Need a React State Management Library?

It depends very much on which and how many components need the data.
Data on which many components depend and do not have to be fetched again and again make the most sense in a parent component.
Data which can be used very limited in a small child component should also be fetched in this component.
The same applies to data that is between these two extremes. A healthy balance prevents components that have nothing to do with the data from being unnecessarily misused as middleman. Furthermore, the parent components render all child components as well. It is therefore all the more important to make sure that the calls happen as selectively as possible.
For data that is needed in each component, I recommend a state manager (React's native reducer and useContext). This prevents prop-drilling, because the data can be easily made available in each component.

Related

React design patterns using redux

I am developing using Presentational & Container design pattern.
Here I have one question.
If all components are connected to the global store, there is no need to divide the components into Presentational components and Container components.
Is there any reason to divide them?
The reason I inquire about this is that if you develop using the Presontational Component & Container Component design pattern, you have to pass props from the parent component to the child component, and I think this is a part that can lower development productivity and cause errors...
So I would like to connect all the components to the global store and use them.
What other problems are there in this case? For example, performance...
"Presentational components" and "Container components" are a pretty old concept that stems from the pre-hooks area. It was nice do have presentational components that could be tested purely on their own - but with the rise of hooks, React components generally house a lot more logic and in most cases, this is fine.
Redux is still a good way of generally moving most logic outside of components - even without a distinction between "presentational" and "container" components. See the Style Guide on this topic
I'd generally recommend reading the Redux Style Guide and if you are still using old-style Redux with connect and switch..case reducers, also read why Redux Toolkit is how to use Redux today
If all components are connected to the global store, there is no need to divide the components into Presentational components and Container components.
First off, any component can be connected to the store (as in, the redux context is available), but you don't need to access state or dispatch actions in every component. So I'd define "connected component" as one that actually uses state or actions.
Is there any reason to divide them?
I'd recommend to simply read state or dispatch actions if and where you need to.
This design pattern from the early redux days is honestly not super helpful and got watered down a bit with hooks and function components (quicker to throw in a useSelector than setting up a connect()ed component).
In some cases you can separate abstract UI logic from global state. As #pailhead pointed out in a comment above, there could be a UserStatus component that defines two different colors for logged in vs. logged out - without being connected to redux. Instead a <UserStatusIndicator> is connected to redux and passes props.isLoggedIn, which is read from state.user.isLoggedIn, to the <UserStatus> component. Imagine the UserStatus component is also reused in an admin panel list that shows the current status of all users in the system - so it's rendered 50 times but independent from redux.
you have to pass props from the parent component to the child
component
Definitely don't do excessive prop drilling, connect these children to redux instead.

About calling API in reactjs

I have a question about calling API in react.
Example in the website. We have a lot of page. Each page has a lot of components. And each component has its own data need to get in server.
I see we have two way to call API is:
First. We call all API of each page in a root of each page then set the data to state. After that, we pass data to children Component.
Second. In each component, we call its API to get its data then set the data to component 's state.
So which is better. I need an explain about that.
Thanks you,
There are many ways to pass Data through out the components.
If the application is small and there are small number of child components you can go by making calls in Root folder.
There would be some components that always doesn't render and only rendered based on specific conditions at this point you can go by making calls from that component.
Using redux and redux thunk is always an option if the data is needed in many components and data can be accessed at any point of time.
As noted in the previous answers/comments you could do either one of these. If you plan to use redux it might be easier to chain the api calls in a single action w/ thunk that gets ran on main component load.
Context or Redux would do you well so you don't have to pass tons of data through prop levels.(prop drilling)
I would suggest Redux, IMO context gets too cluttered and by the time you've properly atomized your code to clean up everything you may as well have just went through the overhead of adding redux.
What you should ask yourself is-
Does it make sense to have all this data load at the same time?
Is it appropriate for some api calls to be made from the components that will use them?
You have creative license to do what works best for you.

React-redux connect: root component connect vs multiple connects [duplicate]

I am new to react and redux. I have a scenario where there are nested components like this.
A > B > C > D
There is a property used in A component and it will be used in D component. So, I have two approaches:
Get state from redux store in component A and then pass it along as props to all it's child components even though it will be used only in D component.
I should connect to redux store in component D and fetch that property from there.
What is the correct approach?
As Dan Abramov, author of redux says in this issue
Both approaches of passing props down to children or connecting them
to the store are appropriate, however having nested connect()
components is actually going to give you more performance. The
downside is they're slightly more coupled to the application and
slightly harder to test, but that may not be a big issue.
He has also articulated a nice rule of thumb to follow on reddit
I do it this way:
Start by using one container and several presentational components
As presentational component tree grows, “middle” components start to pass too many props down
At this point, I wrap some leaf components into containers so that “middle” components don’t need to accept and pass down props that are
completely unrelated to them
Repeat
He has even tweeted regarding this:
Try to keep your presentation components separate. Create container
components by connecting them when it’s convenient.Whenever you feel like you’re duplicating code in parent components to provide data for same kinds of children, time to extract a container.
So in simple words:
You can use connect() at any level. Doing so makes the component smart, since it knows where its props come from. A dumb component just has props, and they could come from anywhere. A smart component is coupled to redux; a dumb component is not.
UPDATE: react-redux v7 and above
The same concept applies to useSelectors too. You can receive data in a container component and pass on to your presentational components, if multiple of its children make use of the same data
If however the data used by the children is different, you can choose to use useSelector individually within the child component. This will make sure that only those components re-render which actually need to
I would suggest if you are already using redux in your app then set the property in the redux store and fetch it in the component D.
But if the work flow is really simple and all the data is fetched from a single source per view, you can avoid redux as it is for complex state management.

In Redux, should global state replace component state?

My question is, should I still be using stateful React components or should I move that state into the Redux store?
There is no single true answer for you question.
You have different types of states. You have a state of your models (in terms of MVC) and UI (View) state. In classical MVC your models should not depend on UI. So, here we have a question: is it ok to save UI state (inputs, checkboxes state) in global redux store.
The most general rule, in this case, is to use common sense :). You can choose any of the approaches depending on your needs and it will be ok if it suits better for your situation.
But, let's look at several examples.
global redux store for everything
I know apps, that save whole UI state in global redux store. I mean that every keystroke in any field will fire event and will update the global store.
Pros:
It is easy to track state changes when the whole state is in one place.
You can serialize the whole state for debugging purposes. It can be automatic state saving on errors. Or QA engineer can dump UI state with a special keyboard shortcut and send to developers. Developers can take this serialized state and restore whole UI as it was on QA's machine.
Cons:
Rerender the whole app on every keystroke.
A lot of intermediary state (in global store) that is needed only while user entering some data.
Passing state down to your components. You will use "Container" components for this but the question is should your "Container" components be only top-level components or you should wrap leaf dump components in containers. Both variants are acceptable but in most cases it is better to move state higher (while it makes sense). Read about "Smart vs Dumb" components or "Containers vs Presentational components"
You should manage different types of state (from different sources) in one global store.
UI state in your components.
For example, you have a form. And your form manages the state on your inputs by its own. So you just render it as <Form onSubmit={ (fields) => saveFields(fields) }>
Pros:
Intermidate form state is private to form. You can think that this state does not exist at all, it does not matter for you.
The shape of private state is much easier to change.
Components are more coherent. They are more independent, like simple mini applications inside your larger application.
Cons:
Other components cannot access this state.
There is no single place of storing state.
Different appoaches to state management.
Increases possibilty of situations when there will be more than one source of thruth.
Additional resources:
Presentation from ReactConf 2016 about possible options for managing state in ReactJS apps
Dan Abramov's great post about "Container" and "Presentational" components
Great video tutorial from Dan Abramov "Getting started with redux". It shows how to use presentational components and how to manage app state.
Some general ideas that can be useful:
Handle as less state as possible in your components but not less than required. Stateless components are easier to work with. But remeber that the state will be moved somewhere, so you will need to handle it in any case (it can be store, or presentational wrapper component etc).
Make your components as much independent as possible. You can make good independent components with private state or make them stateless.
Split components into presentational components (context independent) and container components (context dependent).
Move state as high as possible. Prefer saving state in upper level components. It can be not only container components. You can create presentational components that wraps you stateless components just to manage state (they will have no connection to redux)
I recommend reading this Medium post: Presentational and Container Components. It outlines the ideas of using component state for UI state but non-UI state is global (redux). It also suggest a pattern of how to approach that by having container components responsible for managing access to the global state and simple view components that the container passes state to as a prop.
So the answer is a little more complicated in my opinion because there are different types of state.
I highly recommend this free video series that goes into Redux in depth and provides a lot of explanation to build your knowledge up quickly: Getting Started with Redux.
After digging into Redux more and using it on a project to learn, I found myself making use of it to store UI state. The particular use case was a long scrolling div. I wanted the scroll position of the div to be the same when the back button was used. It was super easy to hook the click up to a dispatch to update the state for the current div.scrollTop and then on componentMount (back button pressed, component remounts) simply set the div.scrollTop to the position from state.
So I think it can be very useful to have UI state in Redux too. It is easier to reason about and simple to do. I can see building very powerful UIs this way that do not exhibit the typical UI issues seen with single page applications.

Where should be the line to separate stateful and stateless component in React?

React encourages the use of stateless components as much as possible and have a stateful parent component managing them.
I understand that this can make the stateless components more reusable, and easy to manage.
However, to the extreme, we can always put the state at the top level component, like App.js, and pass down information and callbacks through a long props chain. And if using Flux, the actions can always be dispatched in it too (executed through callbacks).
So I'm wondering what's line to separate stateful and stateless components? And if using Flux, where should the Actions to be dispatched?
--- Add an example ---
Say I have a google docs like web app that have a tool bar and displayed content. I imagine we will have the component structure.
<App>
<Toolbar />
<Content />
</App>
The tool bar has buttons that will affect the display content, say the bold text button.
So should the App pass down onButtonPressed callback props to Toolbar and dispatch Actions in itself, or should let the Toolbar to do it itself?
Should the App pass down contentString props to Content, or let Content itself listen to Store changes?
Thanks!
From my point of view, a simple application could use the pattern of Flux in that way :
Children emit actions.
The application listens to stores and propagates processed data to his children.
With that approach, you have the stateless component, but with a good code organisation without the callback props. But both of your propositions are also correct, it's a decision that you make regarding the size and needs of your application.
If the component that you build will be used outside of your application, don't use flux as much as possible and let the developer choose the wanted approach for his needs.
It's a good question, and it is being solved differently even between different Flux implementations.
I prefer having my state in one high-level component, that sees the "big picrure", and propagate data using props to all the low-level ones. In a good React app, most of the components shouldn't "care" where the data is coming from.
Having a one good structured model instead of several fragmented ones also proves itself to be beneficial so far. (by the way, that can be achieved even using several stores, the high-level component could listen to all of them, and virtually "hold" this big model).
Regarding actions - I prefer having all my "dumb" visualization/ui/display components work with callback props. That way it is easier to re-use them, and it is a good separation of concerns.
In richer components that hold a bit of business logic, I call Reflux actions directly. Usually those are also container components themselves to aforementioned "dumb" ui controllers.
So bottom line - data should flow from as high as possible, actions can be fired from lower components, but always check whether you can achieve the same result with callback props.
To your question - the Toolbar is a complex enough component to have ToolbarActions of its own and call them directly. But the Content component should definitely get its data from above. It's also easier to reason the data flow that way, when the app gets complicated.
Hope that helps. The whole Flux thing is still an art in progress...

Resources