Skip to content

Component Component

NOTE: This component was developed in the days before React Hooks. In most cases, you should probably build your function components using hooks and use a class component in the rare cases you need them. We may deprecate this component in the future.

A dynamic, functional version of React.Component, a component component if you will. Useful for inline lifecycles and state. It's also incredibly composable and used in many other Reach components.

<Component initialState={{ hue: 0 }}>
  {({ setState, state }) => (
    <div style={{ textAlign: "center" }}>
      <button onClick={() => setState({ hue: Math.random() * 360 })}>
        Generate Triad Colorscheme
      <br />
      {[1, 2, 3].map(n => (
            display: "inline-block",
            margin: 10,
            width: "2em",
            height: "2em",
            borderRadius: "50%",
            background: `hsl(${state.hue + n * 120}, 50%, 50%)`,
            transition: "background-color 200ms ease"


npm install @reach/component-component
# or
yarn add @reach/component-component

And then import it:

import Component from "@reach/component-component";


initialState object
getInitialState func
refs object
getRefs func
didMount func
didUpdate func
willUnmount func
getSnapshotBeforeUpdate func
shouldUpdate func
children func
render func


Type: object

An object of initial state.

Count is 10


Type: func: () => object

A function to return intitial state. Use this when initial state is computed.

In the following example, will not be called every time a parent component causes this component to re-render.

<Component getInitialState={() => ({ now: })}>
  {({ state }) => <div>Now is: {}</div>}

However, in the next example, would be called with every re-render, which is not what we want.

// 😭
<Component initialState={{ now: }} />


Type: object

Put any refs you need to keep track of here, stuff like DOM nodes, timers, and subcriptions.


Type: func: () => object

Use this when any of your refs are computed.

  getRefs={() => {
    return {
      input: React.createRef(),
      popupContainer: document.createElement("div")


Type: func: ({ state, props, refs, setState, forceUpdate }) => undefined

Called when the component mounts.

Perhaps you want some async data but don't want to make an entirely new component just for the lifecycles to get it:

  initialState={{ gists: null }}
  didMount={({ setState }) => {
      .then(res => res.json())
      .then(gists => setState({ gists }));
  {({ state }) =>
    state.gists ? (
        { => (
          <li key={}>
            <a href={gist.html_url}>{gist.description ||}</a>
    ) : (

See also React Docs.


Type: func: ({ state, props, refs, setState, forceUpdate, prevProps, prevState }) => undefined

Called when the component updates. See React Docs.


Type: func: ({ state, props, refs }) => undefined

Called when the component will be removed from the page. See React Docs.


Type: func: ({ state, props, refs, prevProps, prevState }) => any

See React Docs.


Type: func: ({ state, props, nextProps, nextState }) => bool

Return true to signify the component needs an update, false if it does not. Useful for wrapping up expensive parts of your app without having to refactor to new components.

For example: often you find just one part of your component is expensive to render, maybe because of a large SVG with a dynamic style or two. Rather than pulling the elements out of your component and putting them in a new PureComponent, you can inline a shoudlUpdate check:

See also React Docs.


Type: node

Usual React children prop.

Hey, I am the child

Type: func: ({ state, props, refs, setState, forceUpdate }) => node

A render prop callback to provide the stateful parts of your component at render time.


Type: func: ({ state, props, refs, setState, forceUpdate }) => node

Todo App Example

Here is a pretty involved example showing just how composable this component is:

  • "App state" containing all todos
  • "Todo state" containing state for a specific todo
  • Updates the document title to the number of todos in the list
  • Optimized todo rendering, avoiding updates if the color has not changed
  • Tracked refs

Todo List

This is kinda weird