Mobx + React simple todolist

by nathanlogan

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} = mobx;
const {observer} = mobxReact;
const {Component} = React;

class Todo {
    id = Math.random();
    @observable title;
    @observable finished = false;
    constructor(title) {
        this.title = title;
    }
}

class TodoList {
    @observable todos = [];
    @computed get unfinishedTodoCount() {
        return this.todos.filter(todo => !todo.finished).length;
    }
}

@observer
class TodoList_Smart extends Component {
		renderItems(items) {
    	let itemsArray = []
    	for (let i = 0; i < items.length; i++) {
        itemsArray.push(<Todo_Dumb todo={items[i]} key={items[i].id} />)
      }
      return itemsArray
    }
    
    render() {
        console.log('todos: ', this.props.todoList.todos)
        if (!this.props.todoList.todos || !this.props.todoList.todos.length) return <div />
        const items = this.renderItems(this.props.todoList.todos)
        
        return <div>
            <ul>
              {items}
              {/*this.props.todoList.todos.map(todo => {
                <Todo_Dumb todo={todo} key={todo.id} />
              })*/}
            </ul>
            Tasks left: {this.props.todoList.unfinishedTodoCount}
            <mobxDevtools.default />
        </div>
    }
}

// const TodoView = observer(({todo}) =>
class Todo_Dumb extends Component {
    render() {
    	console.log(this.props.todo)
	    return <li>
          <input
              type="checkbox"
              checked={this.props.todo.finished}
              onClick={() => this.props.todo.finished = !this.props.todo.finished}
          />{this.props.todo.title}
      </li>
    }
}

const store = new TodoList();

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

store.todos.push(
    new Todo("Get Coffee"),
    new Todo("Write simpler code")
);
store.todos[0].finished = true;

// For Eval button
window.store = store;