react学习笔记 item9 ---双向绑定(mixin)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014607184/article/details/53310619

我们知道在 angular 中数据时双向绑定的;而在 react 中,数据是向一个方向传递:从拥有者到子节点。也就是我们说的单向数据绑定。如果在 react 中要实现双向数据绑定,就得需要借助插件。

React.addons 是为了构建 React 应用而放置的一些有用工具的地方,其中包含了一些有用的插件,其中就有 用于简化用户表单输入数据和组件 state 之间的双向数据绑定——LinkedStateMixin。要使用这些插件,需要用 react-with-addons.js 替换常规的React.js。

虽然 LinkedStateMixin 大大简化了用户表单输入数据和组件 state 之间的双向数据绑定,但是 Facebook 官网在 v15. 版本之后就不赞成使用了,在 react 官网文档中可以看到这样一段话:

Note: LinkedStateMixin is deprecated as of React v15. The recommendation is to explicitly set the value and change handler, instead of using LinkedStateMixin.

官方文档建议我们还是明确地设置 value 以及 onChange 函数代替 LinkedStateMixin 实现表单的双向数据绑定(react 内部始终是单向数据绑定)。但是作为了学习,这里还是简单的介绍一下利用 LinkedStateMixin 来实现双向数据绑定。

1、使用LinkedStateMixin前后对比

示例1是一个简单的没有使用LinkedStateMixin的表单示例:

// 示例1
var NoLink = React.createClass({
  getInitialState: function() {
    return {message: 'Hello!'};
  },

  handleChange: function(event) {
    this.setState({message: event.target.value});
  },

  render: function() {
    var message = this.state.message;
    return <input type="text" value={message} onChange={this.handleChange} />;
  }
});

这段代码运行地很好,数据如何流动是非常清晰的,但是,如果表单有大量的字段,我们就需要写很多 handleChange 代码就会很冗长了。下面使用LinkedStateMixin来简化:

// 示例2
var WithLink = React.createClass({
  mixins: [React.addons.LinkedStateMixin],
  getInitialState: function() {
    return {message: 'Hello!'};
  },

  render: function() {
    return <input type="text" valueLink={this.linkState('message')} />;
  }
});

LinkedStateMixin 给 React 组件添加一个叫做 linkState() 的方法。linkState()返回一个 valueLink 对象,包含 React state 当前的值和一个用来改变它的回调函数。valueLink 对象可以在树中作为 props 被向上传递或者向下传递。

这里有一点需要注意,对于 checkbox 和 radio 的 value 属性,有一个特殊的行为,如果 checkbox 和 radio 被选中(默认是on),value属性值将会在表单提交的时候发送出去。当 checkbox 和 radio 被选中或者取消选中的时候,value属性是不会更新的。对于checkbox 和 radio ,应该使用checkLink而不是valueLink:

<input type="checkbox" checkedLink={this.linkState('booleanValue')} />

2、底层原理

LinkedStateMixin的实现其实比较简单,下面简单介绍一下其底层原理。

不含 LinkedStateMixin 的 valueLink

// 示例3
var WithoutMixin = React.createClass({
  getInitialState: function() {
    return {message: 'Hello!'};
  },

  handleChange: function(newValue) {
    this.setState({message: newValue});
  },

  render: function() {
    var valueLink = {
      value: this.state.message,
      requestChange: this.handleChange
    };
    return <input type="text" valueLink={valueLink} />;
  }
});

从上述代码中可以看出,valueLink对象是只包含 value 和 requestChange 属性的简单对象。 LinkedStateMixin 同样简单:通过 this.state 来调用状态值以及利用回调函数来调用 this.setState() 来重设状态值。

不含 valueLink 的 LinkedStateMixin

示例4
var WithoutLink = React.createClass({
  mixins: [React.addons.LinkedStateMixin],
  getInitialState: function() {
    return {message: 'Hello!'};
  },

  render: function() {
    var valueLink = this.linkState('message');
    var handleChange = function(e) {
      valueLink.requestChange(e.target.value);
    };
    return <input type="text" value={valueLink.value} onChange={handleChange} />;
  }
});

valueLink 属性也很简单。它简单地处理 onChange 事件,然后调用this.props.valueLink.requestChange(),同时也用 this.props.valueLink.value 替换this.props.value。

3、简单示例

// 示例5
var EasyForm = React.createClass({
    mixins: [ React.addons.LinkedStateMixin ],
    getInitialState:function(){
        return {
            message: 'react is awesome!',
            isReactAwesome: true,
        }
    },
    render:function(){
        return (
            <div>
                <h1>我想说: {this.state.message}</h1>
                <input type="text" valueLink={this.linkState('message')} />

                <h2>React是不是很好用? {this.state.isReactAwesome?'非常好用!':'一般般。。。'}</h2>
                <br/>
                <span>如果觉得React很好用请打钩:
                <input type="checkbox" checkedLink={this.linkState('isReactAwesome') } />
                </span>
                <br/>
                <SubComp messageLink={ this.linkState('message') } likeLink={this.linkState('isReactAwesome')} />

            </div>
        )
    }
});

var SubComp = React.createClass({
    render:function(){
        return (
            <div>
                <h3>这是个子组件内容</h3>
                <span>输入文本:
                <input type="text" valueLink={ this.props.messageLink } />
                </span>
                <br />
                <span>
                如果觉得React很好用请打钩:
                <input type="checkbox" checkedLink = {this.props.likeLink } />
                </span>
            </div>
        )
    }
});

在示例5中,把 valueLink 当做 props 传递到了子组件,因此改变父组件或者子组件时,会互相影响。渲染结果如下:

这里写图片描述

猜你喜欢

转载自blog.csdn.net/u014607184/article/details/53310619