Ajay Gaur
Ajay Gaur

Reputation: 5280

What is parent-child coupling in react and how does it relate to context?

I was reading the Context > Parent-child coupling documentation of React. I was unable to get what parent-child coupling from the documentation. Typically this line :

By passing down the relevant info in the Menu component, each MenuItem can communicate back to the containing Menu component.

The code is:

<Menu>
  <MenuItem>aubergine</MenuItem>
  <MenuItem>butternut squash</MenuItem>
  <MenuItem>clementine</MenuItem>
</Menu>

Upvotes: 4

Views: 743

Answers (2)

Vitaly Kuznetsov
Vitaly Kuznetsov

Reputation: 1763

Consider the example:

ReactDOM.render(
  <Menu>
    <MenuItem>aubergine</MenuItem>
    <MenuItem>butternut squash</MenuItem>
    <MenuItem>clementine</MenuItem>
  </Menu>, mountNode
);

This can occur when Menu is implemented in the library code and doesn't have access to MenuItem, or MenuItems are shuffled with other arbitrary components within Menu.

Menu is the parent, but not the owner of the MenuItem, thus, it can't set the props on MenuItems directly. One way to work this around is to clone each child with new props. But if there are various types of nested components, some of them can receive redundant props.

Another way is to pass the data from Menu within the context and let arbitrary child components access it.

Upvotes: 1

lux
lux

Reputation: 8450

As the article mentions, data flow in React is typically done by passing props from a parent to a child component. However, in some cases this prop sharing can become tedious, and in these cases, we'd use context.

The example in the document describes how continually threading a color prop would eventually become an annoyance, however in most cases you'd utilize context when the prop chain is much deeper than two or three levels. A better example might be the store in Redux.

For instance, those that use Redux, but don't implement react-redux, must access the store from the context. Now, let's say you have a very deeply nested component (grandchildren of grandchildren), and it needs access to the store - well, you can either:

  1. Pass store down via props. However, this means any intermediary component that doesn't need access to the store must have it as a prop nonetheless in order to pass it on to the child somewhere below it does that require it. Adding bulk and boilerplate.
  2. Attach the store to context at a high level component. As a result any child component that specifies a contextTypes within itself will have access to the context, and therefore the store. By doing so, we don't have to worry about injecting any intermediary component with unnecessary props, since we can just access the context.

Keep in mind, context is opt-in, therefore only components that explicitly specify contextTypes will have access to context, if one was so defined above it.

Using props

Parent (Passes props with a store property)
|
+-> props -> Child
           |
           +-> props -> Grandchild
                        |
                        +-> props -> Great-Grandchild 
                                     |
                                     +-> render() -> this.props.store.getState().message  

Using context

Parent (Defines childContextTypes with store property)
|
+ -> Child
     |
     + -> Grandchild
          |
          + ->  Great-Grandchild (Opts-in by defining contextTypes with a store property)
                |
                +-> render() -> this.context.store.getState().message  

UPDATE (with reference to this question posted by JMM):

What API is it referring to?

My understanding is that this refers to the ability for parent components to store functions on context, which can be accessed and invoked by child components, thereby creating a scoped API.

What does it mean: each MenuItem can communicate back to the containing Menu component.

Per the above, if a function were declared on context, and MenuItem opted-in via contextTypes to obtain the function, MenuItem could invoke it, thereby communicating with another component.

Upvotes: 2

Related Questions