双向绑定辅助工具

最后更新于:2022-04-01 20:48:04

`ReactLink`是一种简单表达React双向绑定的方式。 > 注意: > > 如果你是这个框架的初学者,记住`ReactLink`对于大多数应用来说都是不需要的,应该谨慎使用。 在React里面,数据流是一个方向的:从拥有者到子节点。这是因为根据[the Von Neumann model of computing](http://en.wikipedia.org/wiki/Von_Neumann_architecture),数据仅向一个方向传递。你可以认为它是`单向数据绑定`。 然而,有很多应用需要你读取一些数据,然后传回给你的程序。例如,在开发表单的时候,当你接收到用户输入时,你将会频繁地想更新某些React `state`。或者你想在JavaScript中演算布局,然后反应到某些DOM元素的尺寸上。 在React中,你可以通过监听一个“change”事件来实现这个功能,从你的数据源(通常是DOM)读取,然后在你某个组件上调用`setState()`。"关闭数据流循环"明显会引导写出更加容易理解的和维护的程序。查看[我们的表单文档](http://reactjs.cn/react/docs/forms.html)来获取更多信息。 双向绑定 -- 隐式地强制在DOM里面的数据总是和某些React `state`保持一致 -- 是简明的,并且支持非常多的应用。我们已经提供了`ReactLink`:如上所述,是一种设置通用数据流循环模型的语法糖,或者说“关联”某些数据到React `state`。 > 注意: > > ReactLink仅仅是一个`onChange`/`setState()`模式的简单包装和约定。它不会从根本上改变数据在你的React应用中如何流动。 ## ReactLink: 前后对比 这是一个简单的表单示例,没有使用`ReactLink`: ~~~ 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 ; } }); ~~~ 这段代码运行地很好,数据如何流动是非常清晰的,但是,如果表单有大量的字段,代码就会很冗长了。让我们使用`ReactLink`来减少打字输入: ~~~ var WithLink = React.createClass({ mixins: [React.addons.LinkedStateMixin], getInitialState: function() { return {message: 'Hello!'}; }, render: function() { return ; } }); ~~~ `LinkedStateMixin`给你的React组件添加一个叫做`linkState()`的方法。`linkState()`返回一个`ReactLink`对象,包含React state当前的值和一个用来改变它的回调函数。 `ReactLink`对象可以在树中作为props被向上传递或者向下传递,so it's easy (and explicit) to set up two-way binding between a component deep in the hierarchy and state that lives higher in the hierarchy. 注意,对于checkbox的`value`属性,有一个特殊的行为,如果checkbox被选中(默认是`on`),`value`属性值将会在表单提交的时候发送出去。当checkbox被选中或者取消选中的时候,`value`属性是不会更新的。对于checkbox,你应该使用`checkLink`而不是`valueLink`: ~~~ ~~~ ## 底层原理(Under the Hood) 对于`ReactLink`,有两块儿:你创建`ReactLink`实例的地方和你使用它的地方。为了证明`ReactLink`是多么的简单,让我们单独地重写每一块儿,以便显得更加明了。 ### 不带ReactLink的LinkedStateMixin(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 ; } }); ~~~ 如你所见,`ReactLink`对象是非常简单的,仅仅有一个`value`和`requestChange`属性。`LinkedStateMixin`也同样简单:它仅占据这些字段,用来自于`this.state`的值和一个调用`this.setState()`的回调函数。(And `LinkedStateMixin` is similarly simple: it just populates those fields with a value from `this.state` and a callback that calls`this.setState()`.) ### 不带valueLink的ReactLink(ReactLink Without valueLink) ~~~ 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 ; } }); ~~~ `valueLink`属性也很简单。它简单地处理`onChange`事件,然后调用`this.props.valueLink.requestChange()`,同时也用`this.props.valueLink.value`替换`this.props.value`。就这么简单!
';