FunctionAsChild

There is a pattern that is gaining consensus within the React community, and it is known as FunctionAsChild. It is widely used in the popular library react-motion, which we will see in Chapter 6Write Code for the Browser.

The main concept is that, instead of passing a child in the form of a component, we define a function that can receive parameters from the parent.

Let's see what it looks like:

  const FunctionAsChild = ({ children }) => children();

FunctionAsChild.propTypes = {
children: func.isRequired
};

As you can see, FunctionAsChild is a component that has a children property defined as a function and, instead of being used as a JSX expression, it gets called.

The preceding component can be used in the following way:

  <FunctionAsChild> 
{() => <div>Hello, World!</div>}
</FunctionAsChild>

It is as simple as it looks: the children function is fired in the render method of the parent, and it returns the Hello, World! text wrapped in a div, which is displayed on the screen.

Let's delve into a more meaningful example where the parent component passes some parameters to the children function.

Create a Name component that expects a function as children and passes it the string World:

  const Name = ({ children }) => children('World');

Name.propTypes = {
children: func.isRequired
};

The preceding component can be used in the following way:

  <Name> 
{name => <div>Hello, {name}!</div>}
</Name>

The snippet renders Hello, World! again, but this time the name has been passed by the parent. It should be clear how this pattern works, so let's look at the advantages of this approach.

The first benefit is that we can wrap components, passing them variables at runtime rather than fixed properties, as we do with HoCs.

A good example is a Fetch component that loads some data from an API endpoint and returns it to the children function:

  <Fetch url="..."> 
{data => <List data={data} />}
</Fetch>

Secondly, composing components with this approach does not force the children to use some predefined prop names. Since the function receives variables, their names can be decided by the developers who use the component. That makes the FunctionAsChild solution more flexible.

Last but not least, the wrapper is highly reusable because it does not make any assumptions about the children it receives—it just expects a function.

Due to this, the same FunctionAsChild component can be used in different parts of the application, serving various children components.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.149.251.154