1 return ( 2 <div> 3 <header className="header"> 4 <h1>todos</h1> 5 <input 6 ref="newField" 7 className="new-todo" 8 placeholder="What needs to be done?" 9 onKeyDown={this.handleNewTodoKeyDown} 10 autoFocus={true} 11 /> 12 </header> 13 {main} 14 {footer} 15 </div> 16 );
该标签事实上为3个模块组成的了:header部分、body部分、footer部分,模块与模块之间的通信依赖便是model数据了,因为这里最终的渲染皆在app的render处,而render处渲染所有标签全部共同依赖于一个model,就算这里依赖于多个model,只要是统一在render处做展示即可。
流程分析我们前面理清了整个脉络,接下来我们理一理几个关键脉络:
① 新增
TodoApp为其头部input标签绑定了一个onKeyDown事件,事件代理到了handleNewTodoKeyDown:
1 handleNewTodoKeyDown: function (event) { 2 if (event.keyCode !== ENTER_KEY) { 3 return; 4 } 5 6 event.preventDefault(); val = React.findDOMNode(this.refs.newField).value.trim(); (val) { 11 this.props.model.addTodo(val); 12 React.findDOMNode(this.refs.newField).value = ''; 13 } 14 },
因为用户输入的数据不能由属性或者状态值获取,这里使用了dom操作的方法获取输入数据,这里的钩子是ref,事件触发了model新增一条记录,并且将文本框置为空,现在我们进入model新增的逻辑:
1 app.TodoModel.prototype.addTodo = function (title) { 2 this.todos = this.todos.concat({ 3 id: Utils.uuid(), 4 title: title, 5 completed: false 6 }); .inform(); 9 };
model以最简的方式构造了一个数据对象,改变了todos的值,然后通知model发生了变化,而我们都知道informa程序干了两件事:
1 app.TodoModel.prototype.inform = function () { 2 Utils.store(this.key, this.todos); 3 this.onChanges.forEach(function (cb) { cb(); }); 4 };
存储localstorage、触发订阅model变化的回调,也就是:
1 function render() { 2 React.render( 3 <TodoApp model={model}/>, 4 document.getElementsByClassName('todoapp')[0] 5 ); 6 } 7 8 model.subscribe(render);
于是整个标签可耻的重新渲染了,我们再来看看编辑是怎么回事:
② 编辑
这个编辑便与TodoApp没有什么关系了:
{this.props.todo.title}
当双击标签项时,触发了代理的处理程序:
1 handleEdit: function () { 2 this.props.onEdit(); 3 this.setState({editText: this.props.todo.title}); 4 },
这里他做了两个事情:
onEdit,为父标签注入的方法,他这里执行函数作用域是指向this.props的,所以外层定义时指定了作用域:
1 return ( 2 <TodoItem 3 key={todo.id} 4 todo={todo} 5 onToggle={this.toggle.bind(this, todo)} 6 onDestroy={this.destroy.bind(this, todo)} 7 onEdit={this.edit.bind(this, todo)} 8 editing={this.state.editing === todo.id} 9 onSave={this.save.bind(this, todo)} 10 onCancel={this.cancel} 11 /> 12 );
其次,他改变了自身状态机,而状态机或者属性的变化皆会引起标签重新渲染,然后当触发keydown事件后,完成的逻辑便与上面一致了
思考经过之前的学习,我们对React有了一个大概的了解,是时候搬出React设计的初衷了:
Just the ui virtual dom data flow