Introduction to Function-as-child-component pattern

March, 2019

The Function-as-child component or the so called FaCC is one of the most popular patterns in React nowadays. There are numerous libraries using this approach and this article is revealing how it works.

Photo by Pixabay

Function as children pattern

The function as children pattern is one of my favorite. It gives us flexibility and powerful API to pass data around.

Consider the following code.

import 'styles.css';

const Greeting = () => <p>Hello, Poet!</p>;
const App = function () {
  return <Greeting />;
}

ReactDOM.render(
  <App />,
  document.querySelector('.output')
);
import 'styles.css';

const Greeting = () => <p>Hello, Poet!</p>;
const App = function () {
  return <Greeting />;
}

ReactDOM.render(
  <App />,
  document.querySelector('.output')
);
Copy

We have <App> component that renders another component called <Greeting>. To make it a little bit more complicated we will say that the <App> component somehow gathers the name of the current user. And we want to send that name to the <Greeting> component so we see Hello, <user name>. on the screen. Not just Hello Poet!. as it is now.

The problem

The first approach that we may try is to pass the name directly to <Greeting> as a prop. This works but is not very flexible because then <App> can not share what it knows with other components without explicitly passing it down via props.

import 'styles.css';

const Greeting = ({ name }) => {
  return <p>Hello, { name }.</p>;
}
const App = function () {
  const name = 'Jon Snow';
  return <Greeting name={ name }/>;
}

ReactDOM.render(
  <App />,
  document.querySelector('.output')
);
import 'styles.css';

const Greeting = ({ name }) => {
  return <p>Hello, { name }.</p>;
}
const App = function () {
  const name = 'Jon Snow';
  return <Greeting name={ name }/>;
}

ReactDOM.render(
  <App />,
  document.querySelector('.output')
);
Copy

It will be much better if we can somehow send out the name of the user. We don't want to change the place where the data stays but only make it available for other components.

Implementing the pattern

Every React component receives a children prop. Usually that is another React component or maybe some raw data like string or a number. However, this may be also a plain JavaScript object or a function. For example:

import 'styles.css';

const Greeting = ({ name }) => {
  return <p>Hello, { name }.</p>;
}
const App = function ({ children }) {
  const name = 'Jon Snow';
  return children(name);
}

ReactDOM.render(
  <App>
    { (name) => <Greeting name={ name } />}
  </App>,
	document.querySelector('.output')
);
import 'styles.css';

const Greeting = ({ name }) => {
  return <p>Hello, { name }.</p>;
}
const App = function ({ children }) {
  const name = 'Jon Snow';
  return children(name);
}

ReactDOM.render(
  <App>
    { (name) => <Greeting name={ name } />}
  </App>,
	document.querySelector('.output')
);
Copy

As we see here, in the final code we are passing a function:

(name) => <Greeting name={ name } />

That function should return something that React can render. And here is the beauty of the pattern. We may pass whatever arguments we want to that function. In our case that is the name because that is what <Greeting> needs.

In the end the <App> component only deals with the knowledge that it has and its main responsibility is to pass it to the children.


If you like this story consider creating your own here.

“Talk is cheap. Show me the code.”

Full screen

More by
the same passionate developer