So say you have a chat aplication with this component structure:
<ChatApp>
<CurrentUserInfo>...</CurrentUserInfo>
<ChatsPanel>...</ChatsPanel>
<SelectedChatPanel>
<MessagesList>
<MessageBaloon>
<MessageText></MessageText>
<MessageUserHead></MessageUserHead>
</MessageBaloon>
...
</MessagesList>
<SelectedChatPanel>
</ChatApp>
And a Redux state like:
{
currentUser: ...,
chatsList: ...,
selectedChatIndex: ...,
messagesList: [ ... ]
}
How would you make the current user information available to the <MessageUserHead>
component (that will render the current user thumbnail for each message) without having to pass it along all the way from the root component thru all the intermediate components?
In the same way, how would you make information like current language, theme, etc available to every presentational/dumb component in the component tree without resorting to exposing the whole state object?
Sending state/props to another component using the onClick event: So first we store the state/props into the parent component i.e in which component where we trigger the onClick event. Then to pass the state into another component, we simply pass it as a prop.
As an app gets large and complex, you might want to store large, bulky data inside your Redux store and access it inside a component. A Redux store doesn't have a limit on the amount of data stored, so you can pretty much use it to store almost anything, including bulky JSON data, data in table form, etc.
There is no “right” answer for this. Some users prefer to keep every single piece of data in Redux, to maintain a fully serializable and controlled version of their application at all times. Others prefer to keep non-critical or UI state, such as “is this dropdown currently open”, inside a component's internal state.
Passing State to a Component To pass the state into another component, you can pass it as a prop. Then, inside <ExampleComponent /> , you can access the data as this. props. data .
(UPDATE: Having spent some time on option 4, I personally think it's the way to go. I published a library, react-redux-controller built around this approach.)
There are a few approaches that I know of from getting data from your root component, down to your leaf components, through the branches in the middle.
Props chain
The Redux docs, in the context of using react-redux, suggest passing the data down the whole chain of branches via props
. I don't favor this idea, because it couples all the intermediate branch components to whatever today's app structure is. On the bright side, your React code would be fairly pure, and only coupled to Redux itself at the top level.
Selectors in all components
Alternatively, you could use connect
to make data from your Redux store available, irrespective of where you are in the component tree. This decouples your components from one another, but it couples everything to Redux. I would note that the principle author of Redux is not necessarily opposed to this approach. And it's probably more performant, as it prevents re-renders of intermediary components due to changes in props
they don't actually care about.
React children
I haven't thought a great deal about doing things this way, but you could describe your whole app structure at the highest level as nested components, passing in props directly to remote descendants, and using children
to render injected components at the branch levels. However, taken to the extreme, this would make your container component really complicated, especially for intermediate components that have children of more than one type. Not sure if this is really viable at all for that reason.
React context
As first mentioned by @mattclemens, you can use the experimental context api to decouple your intermediate components. Yes, it's "experimental". Yes, the React team definitely doesn't seem to be in love with it. But keep in mind that this is exactly what Redux's connect
uses to inject dispatch
and props from selectors.
I think it strikes a nice balance. Components remain decoupled, because branch components don't need to care about the descendants' dependencies. If you only use connect
at the root to set up the context, then all the descendents only need to couple to React's context API, rather than Redux. Components can freely be rearranged, as long as some ancestor is setting the required context
properties. If the only component that sets context
is the root component, this is trivially true.
The React team compares using context
to global variables, but that feel like an exaggeration. It seems a lot more like dependency injection to me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With