Children as Function

In React, you can pass a function as children to a component:

<MyComponent>
  {() => {
    return "hello world!";
  }}
</MyComponent>

This technique is commonly referred to as render callbacks, and is used by many different libraries such as React Router and React Motion. When applied, rendering logic can be kept in the owner component, instead of being delegated.

Here’s an example where we’ve created a component that automatically measures the size of it’s parent container and passes those parameters down to it’s children.

<AutoSizer>
  {(width, height) => (
    <div style={{width, height}}>
      This div will automatically adjust to the size of it's parent container
    </div>
  )}
</AutoSizer>

This prop is called the “render callback”. That function is able to receive parameters that will be assigned by the child the moment it is called, with the information the child has when doing its stuff. The child is the one to decide if it wants to call that function or not, again depending on its internal logic.

How it works Let’s look at how we might implement our previous example in a fairly naive way:

class AutoSizer extends React.Component {
  state = {
    width: 0,
    height: 0,
  }
  componentDidMount() {
    const node = ReactDOM.findDOMNode(this);
    const parentNode = node.parentNode;

    this.setState({
      width: parentNode.offsetWidth,
      height: parentNode.offsetHeight,
    });
  }
  render() {
    return this.props.children(this.state.width, this.state.height);
  }
}

When to use this pattern

  • Allows you to mix-and-match components

  • Which enables more modular (maintainable) code

  • As an alternative to context

Caveats Because of the no-inline-lambdas ESLint rule, children-as-function currently need to be written as such:

class ComponentThatConsumesAutoSizer extends React.Component {
  render(){
    <AutoSizer children={this.renderAutoSizerChildren} />
  }

  @autobind
  renderAutoSizerChildren(width, height) {
    return (
      <div style={{width, height}}>
        This div will automatically adjust to the size of it's parent container
      </div>
    );
  }
}

The children prop is commonly renamed, typically to render, so don’t be alarmed if you see a component using this naming convention.

Resources

Video Lecture https://courses.reacttraining.com/courses/advanced-react/lectures/3066347

Last updated