TypeScriptでrender props を書いてみた

JavaScriptで書いたことがあったけど、TypeScriptでは初めてだったので。

React Render Props in TypeScript - James Ravenscroft - Medium

Render Props - React

import { storiesOf } from '@storybook/react';
import * as React from 'react';

interface NumberHolderInjectionProps {
  num?: number;
  onChange(num: number): void;
}

interface NumberHolderProps {
  children(injection: NumberHolderInjectionProps): JSX.Element;
}

interface NumberHolderState {
  num?: Number;
}

class NumberHolder extends React.Component<NumberHolderProps, NumberHolderState> {
  state = {
    num: undefined
  };

  onChange = (num: number) => {
    this.setState({
      num
    });
  }

  render(): JSX.Element {
    return this.props.children({
      num: this.state.num,
      onChange: this.onChange
    });
  }
}

interface NumberRendererProps extends NumberHolderInjectionProps {}

let isFirst = true;

const NumberRenderer: React.SFC<NumberRendererProps> = (props) => {
    // コレがないと無限ループする
  if (isFirst) {
    props.onChange(777);
    isFirst = false;
  }

  return (
    <div>
      <p>{ (props.num || 10000) } </p>
    </div>
  );
};

const WrappedNumberRenderer: React.SFC<{}> = (_) => (
  <NumberHolder>
    {(injection: NumberHolderInjectionProps) => <NumberRenderer {...injection} />}
  </NumberHolder>
);

storiesOf('TypeScript&RenderPropsの実験', module)
  .add('Simple実装', () => (
    <WrappedNumberRenderer />
  ));