React Mixin 双向绑定 及 源码分析
来源:互联网 发布:java枚举类的定义 编辑:程序博客网 时间:2024/05/01 03:30
首先从没有使用mixin的例子引入
var BindingExample = React.createClass({ getInitialState: function() { return { text: '' } }, handleChange: function(event) { this.setState({text: event.target.value}) }, render: function() { return <div> <input type="text" placeholder="请输入内容" onChange={this.handleChange} /> <p>{this.state.text}</p> </div> } })React.render(<BindingExample></BindingExample>, document.body);
接下来引入使用mixin的一个例子,没有使用官方的方法
var BindingChange= { handleChange: function(key) { var that = this, newState = {}; return function(e) { newState[key] = e.target.value; that.setState(newState); } } } var BindingExample1 = React.createClass({ mixins: [BindingChange], getInitialState: function() { return { text: "", comment: "" } }, render: function() { return ( <div> <input type="text" placeholder="请输入内容" onChange={this.handleChange('text').bind(this)} /> <textarea onChange={this.handleChange('comment').bind(this)}></textarea> <p>{this.state.text}</p> <p>{this.state.comment}</p> </div> ); } }) React.render(<BindingExample1 />,document.body);
来分析一下这个例子
首先看BindingExample中的render,仔细观察一下实际上和例子一没有什么区别,只是在onChange处理的函数上绑定了上下文,还在在函数里面传了一个值(key)
这个key和state中对应的key值要相同,如例子中input改变的时候是修改state中的"text"这个状态,所以传入"text"。
然后再看BindingExample中的mixins,把BindingChange引用了进来,在引用之后,BindingChange中的东西就会变成BindingExample的东西
所以onChange那里进行bind之后,BindingChange的this指针指向了BindingExample,而不是window。
接着看一下BindingChange。先定义了一个that来保存当前的this,接下里定义了一个对象
为什么要定义一个对象呢。
可以发现,React中setState要修改的状态名字不是一个字符串,也不能解析变量。如果假如onChange事件中传入的key为"text",直接这样修改 setState({key:event.target.value}) 实际上并没有修改text的值,然是去修改了key的值,然而我们并没有在实际的代码中存在key这个状态,所以并不会发生改变。
所以在return的那个函数中newState[key] = e.target.value,这个时候key就可以解析成了text,并且进行了赋值,然后将该对象传入setState中,text这个状态得以改变。
当然,假如传入的是comment这个值,那么这个key实际上就是comment,然后改变的是comment的状态
读到这里大家可能都发现了,mixin做的就是把一些相同的东西抽离出来,就像这个onChange事件,如果没用mixin的话,可能就要写onChange1和onChange2。实际上就像方法的封装一下。当然也有不好的地方,就是查找这个方法的时候可能不会一下子找到。
最后引入官方的例子
var BindingExample2 = React.createClass({ mixins: [React.addons.LinkedStateMixin], getInitialState: function() { return { text: "", comment: "" } }, render: function() { return ( <div> <input type="text" placeholder="请输入内容" valueLink={this.linkState('text')} /> <textarea valueLink={this.linkState('comment')}></textarea> <p>{this.state.text}</p> <p>{this.state.comment}</p> </div> ); } }); React.render(<BindingExample2 />,document.body);对比例子2,我们发现在mixin中使用了React.addons.LinkedStateMixin,这个就是官方封装好的自己的双向绑定的方法
再往下读下去发现onChange事件变成了valueLink,然后使用了方法linkState,而传入的值依旧是这个input想要改变的状态的名字。
我们来看一下官方的这个方法是怎么封装的
var ReactLink = _dereq_(75); var ReactStateSetters = _dereq_(94); var LinkedStateMixin = { linkState: function(key) { return new ReactLink( this.state[key], ReactStateSetters.createStateKeySetter(this, key) ); } }; module.exports = LinkedStateMixin;这个就是方法封装的mixin的LinkedStateMixin方法
官方是这么解释的
ReactLink encapsulates a common pattern in which a component wants to modify a prop received from its parent.
ReactLink封装了一个需要从父级获取值并且修改的一个公有的模式。(实际上就是绑定上下文环境,然后函数的封装)
然后我们去查看ReactStateSetters.createStateKeySetter这个方法是这样写的
createStateKeySetter: function(component, key) { // Memoize the setters. var cache = component.__keySetters || (component.__keySetters = {}); return cache[key] || (cache[key] = createStateKeySetter(component, key)); }传入上下文环境,传入要修改的状态的名字。看到cache,大家也能明白这是缓存的意思,判断是否有这个状态,有的话直接复制,并返回。没有的话就创建一个对象,然后进入(cache[key] = createStateKeySetter(component, key))这个方法中
然后继续找到了createStateKeySetter,他是这个样子的
function createStateKeySetter(component, key) { var partialState = {}; return function stateKeySetter(value) { partialState[key] = value; component.setState(partialState); };}继续传入上下文环境,传入要修改的状态的名字。然后往下读,是不是突然发现很熟悉,这个不就是和例子二中的handleChange是一模一样的。
此篇博文到此就结束了。
- React Mixin 双向绑定 及 源码分析
- React双向绑定Mixin
- react学习笔记 item9 ---双向绑定(mixin)
- React的双向绑定
- vue开发:vue,angular,react数据双向绑定原理分析
- React 双向绑定的实现
- React插件-双向绑定辅助工具
- React插件-双向绑定辅助工具
- react 实现双向绑定以及事件绑定
- React Mixin 的介绍
- ES6+REACT+MIXIN
- React之Mixin
- React(7.1)--mixin
- react 学习--使用Mixin
- React Mixin HelloWorld
- 16、react之 MIxin
- React中的Mixin
- 双向绑定---angular之watch、apply、digest原理深入分析(源码分析)
- jquery分页优化
- Mysql学习总结(20)——MySQL数据库优化的最佳实践
- LA-4060(枚举)
- 环形缓冲区的应用ringbuffer
- 设计模式之装饰者模式
- React Mixin 双向绑定 及 源码分析
- Mysql学习总结(21)——MySQL数据库常见面试题
- 分页,删除操作后在该页码上显示
- Http 分块传输编码 Transfer-Encoding: chunked
- js点击a标签切换不同列表
- android app开发遇到的一些问题(二)
- 对laravel5概念的理解 -- 观察者模式(Event)
- CSS3 2D 转换
- android布局与计算器app编程