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.
Related
I have a situation where one component change is supposed to update other sibling components under same parent. Should I use context or Redux for this?
Or is it okay pass props around via callback function to parent and then to children?
Redux is likely overkill if you only have a small hierarchy of a few components. Use React context to avoid prop drilling where you pass the same props through multiple layers. If you only have one layer, it's fine to use callbacks to pass to children.
If you need global access to this state use Redux (or similar). If you need more localized access to the state use React context.
To answer your question, since they have the same parent it's better to pass callbacks to the children.
So here's my take on this situation. Both Redux and Context help with state management and propagation across components. So here's the deal
Use Redux, if you want the data to be used outside the parent component. For instance, you want the state to be available across your whole application (Global Data or data that is required in 2 or more unrelated components).
Use Context, if only the children of the current component require the data. Not the siblings, not other components in the application - ONLY CHILDREN.
Use props to pass it down to children, only if your component tree is 1 or 2 levels deep. If it is more, use Context
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.
I'm developing a project that uses aggressive composition (each component will have lots of components in its tree and each of its components will have a significant number of components as well) and uses Redux to manage the state.
For example:
<ComponentA>
<ComponentB>
<ComponentC>
...
<ComponentZ>
</ComponentZ>
</ComponenetC>
</ComponentB>
</ComponentA>
Each of these components will have their own functions that can change the app's state.
What would be the most efficient approach to manage all the functions that change the state in the application?
-Use a Container component that connects ComponentA with the actions and pass all the functions down in the components tree
Example:
<ComponentA
funcB={this.props.funcB}
funcC={this.props.funcC}
...
funcZ={this.props.funcZ}
>
-Each component has it's own container so fewer functions will be passed down in the components tree but each component will need an additional component to have the connection:
<ContainerA>
<ContainerB>
...
<ContainerZ />
</Container>
</ContainerA>
One possible approach would be to connect a parent to Redux and let the connected parent drive its children so that children became aware of Redux store changes via the props passed to them by the parent. And change the store by calling parent's methods passed as props. However the grandkids of the connected parent would connect to Redux store themselves but not their children and so forth.
Each of these components will have their own functions that can change the app's state.
If their own functions change their own subset (or slice) of Redux store which other components don't need to be aware of and if the overall store is too big then you can consider splitting it into several independent stores. Link
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 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.