It is a summary on how to use children props, HOC (Higher Order Component), and render props to create layout components. They are not complicated to understand, but it takes some efforts to use them wisely and properly.
const Layout = ({children}) => (
<div>
{children}
</div>
)
// to use
<Layout>
<p>hello worlds</p>
</Layout>
const childrenWithClient = React.cloneElement(children, injectedProps)
We can also pass an arrow function as the child component. It's very useful for creating "helper wrapper" component.
Let's take an example of <Query>
component from apollo-graphql. Here is the usage:
<Query query={SOME_QUERY}>
{({ data, error }) => {
if (error) {
return null
}
if (data) {
return <App data={data} />
}
}}
</Query>
In Query
component, we pass an arrow function as the children
props, let's imagine how Query component can be written:
const Query = ({children}) {
const {data, error} = getData();
return children(data, error);
}
A common user case for HOC and renderProps are: customize the props for components inside Layout component.
const withLayout = Component => {
return () => (
<>
<Component />
</>
)
}
// to use
withLayout(Component)
The idea of render props is to pass a component (a function) as a prop.
Here is the basic example:
const Layout = ({ render }) => (
<>
{render()}
</>
)
// to use
<Layout render={() => <Component/>}>
or
const Layout = ({ content }) => (
<>
{content}
</>
)
// to use
<Layout content={<Component/>}>
or
const Layout = ({ content }) => (
<>
{content}
</>
)
// to use
const content = <div>content</div>
<Layout content={content}/>
Compound component is not for creating Layout component, but it's a special pattern for creating associated component.
The example is really easy. If we write the component in this way:
const App = ... // a component
const SubApp = ... // another component
App.SubApp = SubApp
Then we can use them in this way:
<App/>
<App.SubApp/>