Edit on GitHub

双向绑定辅助

ReactLink 是一个用React表达双向绑定的简单方法。

注意:

在 React v15 中 ReactLink 被弃用了。推荐明确的设置值和变动的处理,而不是使用 ReactLink。

在React里,数据单向流动: 从拥有者到子级。这是因为数据只单向流动the Von Neumann model of computing。你可以把它想象为 “单向数据绑定”。

然而,有很多应用需要你去读某些数据并回流他们到你的程序。例如,当开发forms,你会常常想更新一些React state 当你收到用户输入的时候。或者也许你想在JavaScript完成布局并相应一些DOM元素大小的变化。

在React里,你可以用监听 "change" 事件来实现它,从你的数据源(通常是DOM)读取并在你的某个组件调用 setState() 。明确的"Closing the data flow loop" 致使了更容易理解和维护的程序。更多信息见our forms documentation.

双向绑定 -- 隐含的强迫DOM里的某些值总是和某些React state 同步 -- 简洁并支持大量多样的应用。 我们提供了 ReactLink:设置如上描述的通用数据回流模式的语法糖,或者 "linking" 某些数据结构到 React state.

注意:

ReactLink 只是一层对 onChange/setState() 模式的薄包装。它没有根本性的改变你的React应用里数据如何流动。

ReactLink: 之前和之后 #

这里有一个简单的 不用 ReactLink 的 form 例子:

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} />;
  }
});

这个工作的很好并且数据如何流动很清晰,然而,当有大量的 form fields时,可能会有些冗长。让我们使用 ReactLink 来节省我们的输入:

var LinkedStateMixin = require('react-addons-linked-state-mixin');

var WithLink = React.createClass({
  mixins: [LinkedStateMixin],
  getInitialState: function() {
    return {message: 'Hello!'};
  },
  render: function() {
    return <input type="text" valueLink={this.linkState('message')} />;
  }
});

LinkedStateMixin 添加了一个 linkState() 方法到你的React组件。linkState() 返回一个 ReactLink 包含当前React state值的对象和一个改变它的回调函数。

ReactLink 对象可以作为props在树中上下传递,所以很容易(显示的)在深层次的组件和高层次的state之间 设置双向绑定。

注意 checkboxes 有一个关于他们 value 属性的特殊行为,这个行为是 如果checkbox被选中 值会在表单提交时被发送。 value 不会 checkbox 选中或是不选中时更新。对于checkboxes,你应该用checkedLink 代替 valueLink: <input type="checkbox" checkedLink={this.linkState('booleanValue')} />

引擎盖下 #

这里对 ReactLink有两方面:创建ReactLink的实例以及使用它的地方。为了证明ReactLink有多简单,让我们重写两方面一边更好的理解。

ReactLink Without LinkedStateMixin #

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} />;
  }
});

正如你所见,ReactLink对象是非常简单,只有valuerequestChange属性.并且LinkStateMixin也很简单:它只是作用(populates)于this.state的元素值并且回调名为this.setState()的函数.

ReactLink Without valueLink #

var LinkedStateMixin = require('react-addons-linked-state-mixin');

var WithoutLink = React.createClass({
  mixins: [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.requestChange()代替this.props.value.这就是双向绑定!