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.
Related
In my react application, lets say I have some data which is needed by both a parent component and its immediate child. The application uses redux for state management.
Now, in the child component, I can use useSelector and get the sate. But as I already have the information in the parent (in case it matters, I also got using useSelector), I simply pass props to the child like <Child info={someInfo} />. Here is Child is child component and someInfo is the sate information I got using useSelector.
My question is, should I pass props in this case or get the data using useSelector in child component. Moreover, will passing props be faster than instead of reading using useSelector and vice-versa?
Passing data through props makes the component a functional one or at least more functional. Such components are easier to maintain, test and reuse. It also makes it less dependent on future changes in the store structure. But, as it is often in our lives, there are no things as the only one right way. If your project contains many nested components, passing data all the way down through all layers would make code entangled and complicated.
In my practice, I always make UI components (lists, edits, grids, tables, etc.) as pure functional ones and use them inside business-logic-related components which are connected to store and perform side effects.
I think this is maybe a little opinion-based. Getting it from flux store means there is a hard coupling with store lib. If you pass in the prop, you can reuse the component in another, storeless, application. I've encountered this a lot with some of the components I've made and tend towards passing props in. But again, it can make sense in some cases where the component would never see reuse anyway.
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 my ReactJs application, I have a redux store. In Parent component I am fetching the prop from the redux store. Now, I want to pass this prop to a child component. I have two ways to do this:
1. Send props from parent component to child component.
2. Fetch the prop from the redux store in the child component.
Which way is preferred and why?
Although both will lead to same result. I want to know the difference between the two and which approach is a preferred way.
The answer is kind of opinion based, try next rule thumb:
On each step, if your component is not Readable or Hard to Maintain then you move to the next step.
You start by passing props => Using Context API => State Manager.
The question you're asking is on presentational component VS container component topic.
Containers usually contain business logic, containers are connect to the Redux store as well.
Presenters should only display data from the props you pass in.
There are many benefits that come with such approach. Improved code readability, testability, better separation of concerns and much more.
Continue here - [https://redux.js.org/basics/usage-with-react#presentational-and-container-components][1]
In my opinion, I consider that the structure should be consistent with the rest of your repo. If you connected all the smart containers to redux, continue with that line, so it will be clearer for someone else to read your code.
I know It may sound like a dumb question, But I am not able to get this solved in my head. Please bear with me.
In case when we use a state management system in React like Redux / Mob X, I guess the main purpose of these state management techniques is to provide a single source of Data and a more structured approach of updating it.
Say, I am Using a state management library(MobX) for React, And suppose I have a parent component which makes an http API call and updates the MobX store with the API response. Now I need that data in one of child/nested components.
My Question is, Should I pass that data as a prop to child component or should I enable child component to connect with Central Store and directly get that data ?
by connecting the child to store, I am turning the Child into a class component, which is making it more heavy and React optimisations may not apply. I am defeating the whole purpose of a functional component.
Awaiting replies.
Best Regards,
Lalit
This completely depends on the situation. I would suggest splitting your components up in 2 parts:
Components that could be re-used in other projects
(Higher level) Components that are so specific to this project that they probably never will be re-used.
For components of category 1, I would suggest not using mobx store directly, but instead make pure react components. (eg think of a dropdown, or an ajax dropdown component).
For second part components (think of, header, footer, section components specific for your website). just make them directly interact with the Mobx store, so that you can way quicker code what you need (instead of constantly having to prop everything).
addition
For components of category 1 you can always wrap them with the #inject() method. This way for example you could turn a dropdown component into a UserDropdown component that uses the mobx store for its state. (The inject method injects mobx state as props in the component).
const UserDropDownComponent = mobx.inject(stores => ({users: stores.userStore.users}))(DropDownComponent);
// usage:
<UserDropDownComponent />
Warning
For pure components wont always see changes of mobx state. To Fix this you need to wrap the component in an #observe annotation. Or you have to inject the props by wrapping it into: mobx.toJS(yourMobxStateProperty)
I am running into a situation where I am having to pass in props from the parent container component to the child container components so that the presentational components within the child container have an initial state. Is there another way of approaching this? Is this frowned upon?
Is the data in the Parent Container (the data you say is "from rails") being consumed by Redux? If not, then that is your real problem. Redux should be the one and only source of information for the react containers. Redux, in turn, should accept information from the Rails app and store that information within it's global state.
Once you've achieved this, you now have a single source of truth for all information feeding into the React Containers.
If a sub-component needs any information at all, it should receive them from the parent-container's redux state information.
It is ok to have nested sub-components. Simply continue to pass down information from 1 layer to the next. E.g. ContainerA, which receives name from redux, can render ComponentX with name={this.props.name} and ComponentX can then render ComponentY with name={this.props.name} again. This results in ComponentY being passed the information from Redux, through the parent component and container.
Your app should, naturally, have far more components than containers. That's a good thing. Components are inherently re-usable since they are only tied to a data shape rather than a data source. Use containers sparingly, and only when you want to insert specific information into a series of components.