@ -40,35 +40,49 @@ Context is primarily used when some data needs to be accessible by *many* compon
**If you only want to avoid passing some props through many levels, [component composition](/docs/composition-vs-inheritance.html) is often a simpler solution than context.**
For example, consider a `Page` component that passes a `user` prop several levels down so that a deeply nested `Avatar` component can read it:
For example, consider a `Page` component that passes a `user`and `avatarSize`prop several levels down so that deeply nested `Link` and `Avatar` components can read it:
It might feel redundant to pass down the `user` prop through many levels if in the end only the `Avatar` component really needs it. It's also annoying that whenever the `Avatar` component needs more props from the top, you have to add them at all the intermediate levels too.
It might feel redundant to pass down the `user`and `avatarSize`props through many levels if in the end only the `Avatar` component really needs it. It's also annoying that whenever the `Avatar` component needs more props from the top, you have to add them at all the intermediate levels too.
To solve this issue **without context**, change `PageLayout` and `NavigationBar` to [accept a `children` prop](/docs/composition-vs-inheritance.html#containment). Then the `Page` component could pass `<Avatar user={user} />` down as a child, and neither of the components below would need to know about the `user` prop:
One way to solve this issue **without context** is to [pass down the `Avatar` component itself](/docs/composition-vs-inheritance.html#containment) so that the intermediate components don't need to know about the `user` prop:
```js
function Page(props) {
const user = props.user;
return (
<PageLayout>
<NavigationBar>
<Avataruser={user}/>
</NavigationBar>
</PageLayout>
const userLink = (
<Linkhref={user.permalink}>
<Avataruser={user}size={props.avatarSize}/>
</Link>
);
return <PageLayoutuserLink={userLink}/>;
}
// Now, we have:
<Pageuser={user}/>
// ... which renders ...
<PageLayoutuserLink={...}/>
// ... which renders ...
<NavigationBaruserLink={...}/>
// ... which renders ...
{props.userLink}
```
With this change, only the top-most Page component needs to know about the `Link` and `Avatar` components' use of `user` and `avatarSize`.
This *inversion of control* can make your code cleaner in many cases by reducing the amount of props you need to pass through your application and giving more control to the root components. However, this isn't the right choice in every case: moving more complexity higher in the tree makes those higher-level components more complicated and forces the lower-level components to be more flexible than you may want.
You're not limited to a single child for a component. You may pass multiple children, or even have multiple separate "slots" for children, [as documented here](/docs/composition-vs-inheritance.html#containment):