首先从没有使用mixin的例子引入

[javascript] view plaincopy print?
  1. var BindingExample = React.createClass({
  2. getInitialState: function() {
  3. return {
  4. text: ''
  5. }
  6. },
  7. handleChange: function(event) {
  8. this.setState({text: event.target.value})
  9. },
  10. render: function() {
  11. return <div>
  12. <input type="text" placeholder="请输入内容" onChange={this.handleChange} />
  13. <p>{this.state.text}</p>
  14. </div>
  15. }
  16. })
  17. React.render(<BindingExample></BindingExample>, document.body);

这个例子大家都很熟悉,当input框发生改变的时候,去调用handleChange方法,然后通过setState重新render P标签中的数据

接下来引入使用mixin的一个例子,没有使用官方的方法

[javascript] view plaincopy print?
  1. var BindingChange= {
  2. handleChange: function(key) {
  3. var that = this,
  4. newState = {};
  5. return function(e) {
  6. newState[key] = e.target.value;
  7. that.setState(newState);
  8. }
  9. }
  10. }
  11. var BindingExample1 = React.createClass({
  12. mixins: [BindingChange],
  13. getInitialState: function() {
  14. return {
  15. text: "",
  16. comment: ""
  17. }
  18. },
  19. render: function() {
  20. return (
  21. <div>
  22. <input type="text" placeholder="请输入内容" onChange={this.handleChange('text').bind(this)} />
  23. <textarea onChange={this.handleChange('comment').bind(this)}></textarea>
  24. <p>{this.state.text}</p>
  25. <p>{this.state.comment}</p>
  26. </div>
  27. );
  28. }
  29. })
  30. 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。实际上就像方法的封装一下。当然也有不好的地方,就是查找这个方法的时候可能不会一下子找到。

最后引入官方的例子

[javascript] view plaincopy print?
  1. var BindingExample2 = React.createClass({
  2. mixins: [React.addons.LinkedStateMixin],
  3. getInitialState: function() {
  4. return {
  5. text: "",
  6. comment: ""
  7. }
  8. },
  9. render: function() {
  10. return (
  11. <div>
  12. <input type="text" placeholder="请输入内容" valueLink={this.linkState('text')} />
  13. <textarea valueLink={this.linkState('comment')}></textarea>
  14. <p>{this.state.text}</p>
  15. <p>{this.state.comment}</p>
  16. </div>
  17. );
  18. }
  19. });
  20. React.render(<BindingExample2 />,document.body);

对比例子2,我们发现在mixin中使用了React.addons.LinkedStateMixin,这个就是官方封装好的自己的双向绑定的方法

再往下读下去发现onChange事件变成了valueLink,然后使用了方法linkState,而传入的值依旧是这个input想要改变的状态的名字。

我们来看一下官方的这个方法是怎么封装的

[javascript] view plaincopy print?
  1. var ReactLink = _dereq_(75);
  2. var ReactStateSetters = _dereq_(94);
  3. var LinkedStateMixin = {
  4. linkState: function(key) {
  5. return new ReactLink(
  6. this.state[key],
  7. ReactStateSetters.createStateKeySetter(this, key)
  8. );
  9. }
  10. };
  11. 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这个方法是这样写的

[javascript] view plaincopy print?
  1. createStateKeySetter: function(component, key) {
  2. // Memoize the setters.
  3. var cache = component.__keySetters || (component.__keySetters = {});
  4. return cache[key] || (cache[key] = createStateKeySetter(component, key));
  5. }

传入上下文环境,传入要修改的状态的名字。看到cache,大家也能明白这是缓存的意思,判断是否有这个状态,有的话直接复制,并返回。没有的话就创建一个对象,然后进入(cache[key] = createStateKeySetter(component, key))这个方法中

然后继续找到了createStateKeySetter,他是这个样子的

[javascript] view plaincopy print?
  1. function createStateKeySetter(component, key) {
  2. var partialState = {};
  3. return function stateKeySetter(value) {
  4. partialState[key] = value;
  5. component.setState(partialState);
  6. };
  7. }

继续传入上下文环境,传入要修改的状态的名字。然后往下读,是不是突然发现很熟悉,这个不就是和例子二中的handleChange是一模一样的。

此篇博文到此就结束了。

转载于:https://www.cnblogs.com/rubyxie/articles/5920096.html

react 实现数据双向绑定相关推荐

  1. EngJS(超轻量) 中数据双向绑定如何使用

    Eng github 所有支持数据双向绑定的js工具 ,触发双向关系的基本方式无外乎 wather关系 和  事件关系 两种 . 前者操作数据时 ,后者触发事件时. 下面简单 的介绍Eng 中 的 w ...

  2. Vue的数据双向绑定和Object.defineProperty()

    Vue是前端三大框架之一,也被很多人指责抄袭,说他的两个核心功能,一个数据双向绑定,一个组件化分别抄袭angular的数据双向绑定和react的组件化思想,咱们今天就不谈这种大是大非,当然我也没到达那 ...

  3. 前端笔记之微信小程序(二){{}}插值和MVVM模式数据双向绑定指令API

    一.双花括号{{}}插值和MVVM模式 1.1 体会{{}}插值 index.wxml的标签不是html的那些标签,这里的view就是div. {{}}这样的插值写法,叫做mustache语法.mus ...

  4. Vue基础——VueJS是什么、Vue的优缺点、vue2和vue3的模板区别、MVVM数据双向绑定、Vue的安装和使用、Vue模板语法-文本渲染、常用的vue的指令

    目录 一.VueJS是什么? 二.Vue的优缺点 三.MVVM 数据双向绑定 四.Vue的安装和使用 五.Vue模板语法-文本渲染 六.常用的vue的指令 一.VueJS是什么? 它是一个轻量级MVV ...

  5. 双向绑定 当obj的值修改时_JavaScript进阶之深入理解数据双向绑定

    前言 谈起当前前端最热门的 js 框架,必少不了 Vue.React.Angular,对于大多数人来说,我们更多的是在使用框架,对于框架解决痛点背后使用的基本原理往往关注不多,近期在研读 Vue.js ...

  6. 小猿圈解析vue数据双向绑定的缺点

    vue是当今前端很流行的一种框架,但是vue也是有一定的缺陷的,你有过了解吗?下面小猿圈web前端老师就为你解析一下vue数据双向绑定的缺陷,希望对你有所帮助,下面我们一起了解一下吧. 1.vue 实 ...

  7. vue中通过数据双向绑定给video标签的src赋值,只有第一次有效,怎么解决?

    场景:在一个视频列表页面,点击视频列表,则全屏播放视频.全屏播放是一个公用组件,每次点击视频列表则把该视频的播放地址通过vue的数据双向绑定到组件中的video标签,如下: <video con ...

  8. 数据双向绑定_手把手教你用JavaScript如何实现数据双向绑定

    近几年前端技术栈真是发展的太迅速了,从以前的针对dom操作的框架如jquery,ext.js等框架逐步过渡到当前的mvvm模式,让前端开发者将注意力从dom操作逐渐解脱出来,专注于逻辑的实现,个人认为 ...

  9. 西安电话面试:谈谈Vue数据双向绑定原理,看看你的回答能打几分

    最近我参加了一次来自西安的电话面试(第二轮,技术面),是大厂还是小作坊我在这里按下不表,先来说说这次电面给我留下印象较深的几道面试题,这次先来谈谈Vue的数据双向绑定原理. 情景再现: 当我手机铃声响 ...

最新文章

  1. 在代码中定义一个执行线程的步骤
  2. apk解密工具_手机端操作| Auto.js一键解密/一键加密工具免费分享
  3. 4.6.2 软件测试的步骤
  4. 见微知著(一):解析ctf中的pwn--Fast bin里的UAF
  5. 开发工具 codepen codepen vscode
  6. SQL Server实用经验与技巧大汇集 [转]
  7. linux传文件到其他用户,在linux中将文件从用户复制到另一个文件
  8. Java定时任务中间表,mysql 通过定时任务更新中间表
  9. xmemecached中的一致性hash算法
  10. QT tableWidget的使用及其实例
  11. zabbix item详解
  12. 洛谷P3709 大爷的字符串题(莫队)
  13. 泊车——prescan
  14. 麒麟服务器数据库协议,麒麟服务器神通数据库安装
  15. 竞合关系会是云计算行业主流:阿里云发布新一代数据库
  16. 如何除去Windows的快捷方式小图标
  17. 在手机上怎么提取视频中的音频?就这么简单
  18. onenote for windows 10 部分内容不能同步解决方法
  19. a15仿生芯片和骁龙8gen1 哪个好
  20. 美丽天天秒系统开发模式与美丽天天秒系统源码分享

热门文章

  1. 关于modbus温湿度传感器,IIC热成像仪相关知识点总结
  2. QT5生成可执行文件总结
  3. Bag of Word
  4. 量子计算机到底神在哪里说明文,“九章”量子计算机到底有多神!
  5. 【GANs入门】pytorch-GANs任务迁移-单个目标(数字的生成)
  6. 区块链实现代码详细分析(Python)
  7. 利用GPU训练网络时遇到的一些问题
  8. idea 添加 VUE 的语法
  9. HZOJ Drink
  10. 无线传感网3-2.高效率目标物监控