Mobx + React simple todolist
by zerkalica
HTML
<body>
<script crossorigin src="https://unpkg.com/react@next/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@next/umd/react-dom.development.js"></script>
<script crossorigin src="https://unpkg.com/lom_atom@2/dist/lom_atom.umd.js"></script>
<script crossorigin src="https://unpkg.com/reactive-di@4/dist/reactive-di.umd.js"></script>
<div id="mount">
</div>
</body>
Babel + JSX
// @flow
const {mem, action, force} = lom_atom
const {createReactWrapper, createCreateElement, Injector} = window['reactive-di']
const {render} = ReactDOM
const {createElement, Component} = React
/** @jsx lom_h */
// setup
function ErrorableView({error}: {error: Error}) {
return <div>
{error instanceof mem.Wait
? <div>
Loading...
</div>
: <div>
<h3>Fatal error !</h3>
<div>{error.message}</div>
<pre>
{error.stack.toString()}
</pre>
</div>
}
</div>
}
const lomCreateElement = createCreateElement(
createReactWrapper(
Component,
ErrorableView
),
createElement
)
window['lom_h'] = lomCreateElement
// todo
let tid = 0
class Todo {
id = ++tid;
@mem title;
@mem finished = false;
constructor(title) {
this.title = title;
}
}
function fetchSomeTodos() {
return new Promise(resolve => {
setTimeout(() => resolve([
new Todo('Get Coffee'),
new Todo('Write simpler code')
]), 1500)
})
}
class TodoList {
@force $: TodoList
@mem set todos(next: Todo[] | Error) {}
@mem get todos() {
fetchSomeTodos()
.then(todos => { this.$.todos = todos })
.catch(error => { this.$.todos = error })
throw new mem.Wait()
}
@mem get unfinishedTodoCount() {
return this.todos.filter(todo => !todo.finished).length;
}
}
function TodoListView({todoList}) {
return <div>
<ul>
{todoList.todos.map(todo =>
<TodoView todo={todo} key={todo.id} />
)}
</ul>
Tasks left: {todoList.unfinishedTodoCount}
</div>
}
function TodoListErrorableView({error}: Error) {
return <div>{error instanceof mem.Wait ? 'pending...' : error.message}</div>
}
TodoListView.onError = TodoListErrorableView
function TodoView({todo}) {
...