React Render Props with TypeScript

React render props are a useful tool for sharing logic across multiple components. Think of them as a special case of higher-order component where–instead of creating new child components–different render methods can be injected.

Suppose we have a logical component (call it CounterDataProvider) responsible for managing a count value consumed by components deeper inside the React DOM. If we want to allow different rendering strategies for the count, we can type CounterDataProvider to receive a render prop.

type CounterState = {
  count: number,

type ChildProps = CounterState & {
  increment(d: number): void,

type CounterProps = {
  render(state: ChildProps): React.ReactNode,

Yes, it’s exactly what it sounds like. The props we’ll pass to CounterDataProvider‘s props include a render method that takes in ChildProps and produces a ReactNode–the exact same signature we’d see in a garden-variety Stateless Functional Component (SFC). And that’s exactly what we’ll pass to render!

import * as React from 'react';

class CounterDataProvider extends React.Component<CounterProps, CounterState> {
  readonly state: CounterState = {
    count: 44,

  increment = (delta: number) =>
    this.setState({ count: this.state.count + delta })

  render() {
    return this.props.render({
      increment: this.increment,

export default () => (
    render={(props: ChildProps) => (
        <h1>Count: {props.count}</h1>
        <button onClick={() => props.increment(1)}>+1</button>
        <button onClick={() => props.increment(-1)}>-1</button>

If we wanted to imagine a completely different UI for the counter, no problem! Just give render a different SFC and away you go.

Find a demo of it all working together in the React with TypeScript repository on Github.