Mobx + React simple todolist

HTML

<script src=" https://unpkg.com/mobx/lib/mobx.umd.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.0/react-dom.min.js"></script>
<script src="https://unpkg.com/mobx-react"></script>
<body>
  <div id="mount">
  
  </div>
</body>

Babel + JSX

let {Component} = React;

class Spinner extends Component {  
  componentWillMount() {
    this.observePromise(this.props.promise)
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.promise !== nextProps.promise) {
      this.observePromise(nextProps.promise)
    }
  }
  
  observePromise(p) {
    this.setState({state: 'pending'});
    p.then(v => this.setState({state: 'fulfilled', value: v}), 
           e => this.setState({state: 'rejected', error: e}))
  }

  render() {
    if (this.props.promise == null)      return null;
    if (this.state.state == 'pending')   return <img src="https://media.giphy.com/media/10kTz4r3ishQwU/giphy.gif" />
    if (this.state.state == 'rejected')  return <div>Error: {this.state.error}</div>
    if (this.state.state == 'fulfilled') return this.props.whenResolved(this.state.value)
  }
}


function timeout(N) {
  return new Promise(resolve => setTimeout(resolve, N))
}

const p = timeout(2000).then(() => "Hello world")
const Main = () =>
  <div>
    <Spinner promise={p} whenResolved={data => 
    	<div style={{"font-size": "3rem"}}>{data}</div>
    } />
  </div>

ReactDOM.render(<Main />, document.getElementById('mount'));