Mobx + React simple todolist
HTML
<script src="https://unpkg.com/react@15/dist/react.min.js"></script>
<script src="https://unpkg.com/react-dom@15/dist/react-dom.min.js"></script>
<script src="https://unpkg.com/mobx@3/lib/mobx.umd.js"></script>
<script src="https://unpkg.com/mobx-react@4"></script>
<script src="https://unpkg.com/mobx-react-devtools@4"></script>
<body>
<div id="mount">
</div>
<hr/>
<button onclick="eval(prompt('javascript', 'store.todos[0].title += \'!\''))">Eval some JS</button>
</body>
Babel + JSX
const {observable, computed, toJS} = mobx;
const {observer} = mobxReact;
const {Component} = React;
// container/smart component
@observer
class TodoListContainer extends Component {
onCheckClick(position) {
this.props.todoList.todos[position].finished = !this.props.todoList.todos[position].finished
}
editTitle(position, newTitle){
this.props.todoList.todos[position].title = newTitle
}
render() {
const onCheckClick = this.onCheckClick.bind(this)
const editTitle = this.editTitle.bind(this)
// IMPORTANT!!! note the usage of toJS() here
return (
<div>
<TodoListView
todos={toJS(this.props.todoList.todos)}
editTitle={editTitle}
onCheckClick={onCheckClick}
/>
Tasks left: {this.props.todoList.unfinishedTodoCount}
<mobxDevtools.default />
</div>
)
}
}
// presentational/dumb component
class TodoListView extends Component {
render() {
const editTitle = this.props.editTitle
const onCheckClick = this.props.onCheckClick
return <div>
<ul>
{this.props.todos.map((todo, i) =>
<li>
<input
type="checkbox"
checked={todo.finished}
onClick={() => onCheckClick(i)}
/>
{todo.title}
<button onClick={() => { editTitle(i, todo.title + '!!!')}}>Add Emphasis!</button>
</li>
)}
</ul>
</div>
}
}
/** STORE STUFF **/
class Todo {
id = Math.random();
@observable title;
@observable finished = false;
constructor(title) {
this.title = title;
}
}
class TodoListStore {
@observable todos = [];
@computed get unfinishedTodoCount() {
return this.todos.filter(todo => !todo.finished).length;
}
}
const store = new TodoListStore();
/** END STORE STUFF **/
ReactDOM.render(<TodoListContainer todoList={store} />, document.getElementById('mount'));
/** TWEAK THE STORE TO SHOW UPDATES...