此文章是翻译Two-way Binding Helpers这篇React(版本v15.4.0)官方文档。
Two-way Binding Helpers
注意:
LinkedStateMixin
在React v15 被废弃掉了。建议明确地设置value 以及更改句柄,而是不是用LinkedStateMixin
。
Importing
1 | import LinkedStateMixin from 'react-addons-linked-state-mixin' // ES6 |
Overview
LinkedStateMixin
是表达React 的双向绑定的一种简单方法。
在React 中,数据流是单向的:从拥有者到孩子。这是因为在the Von Neumann model of computing 中数据只能向一个方向流动。你可以认为它是“单向绑定的”。
然而,需要引诱需要你去读取数据并将其返回到你的程序中。例如,当开发表单时,当你收到用户的输入,你需要更新React 的state
。或者可能你想要在JavaScript 中执行布局去对DOM element 大小的改变做出响应。
在React 中,你将可以通过监听“change”事件,读取从你的数据源(通常是DOM),在你的component 中的一个上调用setState()
去实现它。“关闭数据流循环 (closing the data flow loop)”明确地导致更容易理解和更容易维护程序。查看our form documentation获取更多信息。
双向绑定 – 隐式执行DOM 中的一些值总是同一些React state
保持一致 – 是简洁的,支持多种应用。我们已经提供了LinkedStateMixin
:上述设置通过数据流动模式的语法它,或者“链接(linking)”一些数据源到React 的state
。
Note:
LinkedStateMixin
只是一个简单的包裹器,onChange/setState()
模式的规则。它并没有从根本上改变在你的React 应用中数据流动。
LinkedStateMixin: Before and After
这是一个不使用LinkedStateMixin
的简单的表单例子:
1 | var NoLink = React.createClass({ |
这工作的非常好并且数据的流动也非常清晰,然后,如果有许多表单域,它可能会有点冗余。使用LinkedStateMixin
去减少打字:
1 | var WithLink = React.createClass({ |
LinkedStateMixin
添加了linkState()
方法到你的React component 中。linkState()
返回了一个包含当前React state 的值的valueLink
对象,一个回调函数去改变它。
valueLink
对象可以作为props, 在向下或向上传入树中,所以它很容易的(明确的)在一个深入层级的component和位于高层级的state之间设置双向绑定。
注意到复选框(checkbox)有一个特殊的行为关于它们的value
特性(attribute),这个值将会在表单提交的时候送出如果这个复选框被选定(默认是on
)。value
特性不被更新当复选框被选定或没有选定。对于复选框,你应该使用checkedLink
替代valueLink
:<input type="checkbox" checkedLink={this.linkState('booleanValue')}/>
。
Under the Hood
LinkedStateMixin
有两个方面:你创建valueLink
实例的位置和你使用它的位置。为了证明LinkedStateMixin
是多么简单,让我们分开重写每一方面使它更清晰。
valueLink Without LinkedStateMixin
1 | var WithoutMixin = React.createClass({ |
就像你看到的那样,valueLink
对象是一个非常简单的对象,它值有一个value
和一个requestChange
prop。和LinkedStateMixin
是同样的简单:它只是使用来自this.state
的值和一个调用this.setState()
的回调函数填充这些字段。
LinkedStateMixin Without valueLink
1 | var WithoutValue = React.createClass({ |
valueLink
prop 也是相当的简单。它简单地控制onChange
事件,调用this.props.valueLink.requestChange()
,也使用this.props.valueLink.value
替代this.props.value
。好了!