SHARE
TWEET

Untitled

a guest May 19th, 2017 39 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. class AppState {
  2.   constructor(attrs) {
  3.     this.attrs = attrs || {
  4.       todos: []
  5.     }
  6.   }
  7.  
  8.   clone() {
  9.     const attrs = Object.assign({}, this.attrs)
  10.     attrs.todos = attrs.todos.map(todo => Object.assign({}, todo))
  11.     return new AppState(attrs)
  12.   }
  13.  
  14.   addTodo(todo) {
  15.     const this_ = this.clone()
  16.     todo.id = (Math.random() * 99999).toString(36)
  17.     this_.attrs.todos.push(todo)
  18.     return this_
  19.   }
  20.  
  21.   removeTodo(todo) {
  22.     const this_ = this.clone()
  23.     this_.attrs.todos = this.attrs.todos.filter(todo => todo !== todo)
  24.     return this_
  25.   }
  26.  
  27.   completeTodo(todo) {
  28.     const this_ = this.clone()
  29.     const i = this.attrs.todos.indexOf(todo)
  30.     this_.attrs.todos[i].complete = true
  31.     return this_
  32.   }
  33. }
  34.  
  35. class TodoList extends React.Component {
  36.   static Item(props) {
  37.     const { todo, onCompletionToggleRequest, onRemoveTodoRequest } = props
  38.     const classes = ['todo-list-item']
  39.  
  40.     if (todo.completed) {
  41.       classes.push('todo-list-item-completed')
  42.     }
  43.  
  44.     return (
  45.       <div className={classes.join(' ')}>
  46.         <div className="todo-list-item-col todo-list-item-col-complete">
  47.           <input
  48.             type="checkbox"
  49.             checked={todo.completed}
  50.             onChange={onCompletionToggleRequest}
  51.           />
  52.         </div>
  53.         <div className="todo-list-item-col todo-list-item-col-text">
  54.           {todo.text}
  55.         </div>
  56.         <div className="todo-list-item-col todo-list-item-col-remove">
  57.           <button onClick={onRemoveTodoRequest}>x</button>
  58.         </div>
  59.       </div>
  60.     )
  61.   }
  62.  
  63.   render() {
  64.     return (
  65.       <div className="todo-list">
  66.         {this.props.todos
  67.           .map(todo => {
  68.             return (
  69.               <TodoList.Item
  70.                 todo={todo}
  71.                 onCompletionToggleRequest={() => this.props.onCompletionToggleRequest(todo)}
  72.                 onRemoveTodoRequest={() => this.props.onRemoveTodoRequest(todo)}
  73.                 key={todo.id}
  74.               />
  75.             )
  76.           })
  77.         }
  78.       </div>
  79.     )
  80.   }
  81. }
  82.  
  83. class TodoCreator extends React.Component {
  84.   constructor(props) {
  85.     super(props)
  86.     this.state = {
  87.       text: '',
  88.     }
  89.     this.onFormSubmit = this.onFormSubmit.bind(this)
  90.     this.onTextChange = this.onTextChange.bind(this)
  91.   }
  92.  
  93.   render() {
  94.     return (
  95.       <form className="todo-creator" onSubmit={this.onFormSubmit}>
  96.         <input type="text" onChange={this.onTextChange} />
  97.       </form>
  98.     )
  99.   }
  100.  
  101.   onFormSubmit(e) {
  102.     e.preventDefault()
  103.     this.props.onTodoSubmit({
  104.       text: e.target.value,
  105.       completed: false,
  106.     })
  107.   }
  108.  
  109.   onTextChange(e) {
  110.     this.setState({ text: e.target.value })
  111.   }
  112. }
  113.  
  114. class App extends React.Component {
  115.   constructor(props) {
  116.     super(props)
  117.     this.onCompletionToggleRequest = this.onCompletionToggleRequest.bind(this)
  118.     this.onTodoSubmit = this.onTodoSubmit.bind(this)
  119.     this.onRemoveTodoRequest = this.onRemoveTodoRequest.bind(this)
  120.   }
  121.  
  122.   render() {
  123.     return (
  124.       <div className="app-todos">
  125.         <TodoCreator onTodoSubmit={this.onTodoSubmit} />
  126.         <TodoList
  127.           todos={this.props.todos}
  128.           onCompletionToggleRequest={this.onCompletionToggleRequest}
  129.           onRemoveTodoRequest={this.onRemoveTodoRequest}
  130.         />
  131.       </div>
  132.     )
  133.   }
  134.  
  135.   onCompletionToggleRequest(todo) {
  136.     this.props.changeState(state => state.completeTodo(todo))
  137.   }
  138.  
  139.   onTodoSubmit(todo) {
  140.     this.props.changeState(state => state.addTodo(todo))
  141.   }
  142.  
  143.   onRemoveTodoRequest(todo) {
  144.     this.props.changeState(state => state.removeTodo(todo))
  145.   }
  146. }
  147.  
  148. let state = new AppState()
  149.  
  150. const changeState = fn => {
  151.   state = fn(state)
  152.  
  153.   ReactDOM.render(
  154.     document.body,
  155.     <App ...state changeState={changeState} />
  156.   )
  157. }
  158.  
  159. changeState(state => state)
RAW Paste Data
Top