Async atom example

Compare with Async redux-saga example: https://jsfiddle.net/zerkalica/3ogxg2sk/

by zerkalica

HTML

<body>
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script crossorigin src="https://unpkg.com/urc@1/dist/urc.umd.js"></script>
<script crossorigin src="https://unpkg.com/lom_atom@4/dist/lom_atom.umd.js"></script>

<div id="mount">
    </div>
</body>

Babel + JSX

// @flow
const {mem, action, ReactAtom} = lom_atom
const {createConnect} = urc
const {render} = ReactDOM
const {createElement, Component} = React

// initialization
function ErrorableView({error}) {
  if (!(error instanceof Error)) return <div>Loading...</div>
  const retry = mem.retry(error)

  return <div>
    <pre>{error.stack.toString()}</pre>
    {retry && <button onClick={retry}>Retry</button>}
  </div>
}

const connect = createConnect({
  BaseComponent: Component,
  renderError: ErrorableView,
  ReactAtom
})

// main

class Store {
  @mem emulateError = false
  @mem get game() {
    throw fetch('https://dog.ceo/api/breeds/image/random')
      .then(res => res.json())
      .then(data => {
        return {url: data.message}
    })
  }

  @action reset() {
    mem.cache(this.game)
  }
}

const ImgView = connect(({store}) =>
    <p><img src={store.game.url}/></p>
)

const HelloView = connect(({store}) =>
  <div>
    <button onClick={store.reset}>Show dog</button>
    <ImgView store={store} />
  </div>
)

const store = new Store()

ReactDOM.render(<HelloView store={store}/>, document.getElementById('mount'));