在React.js表单组件中使用状态或引用?
我开始与React.js和我想要做一个简单的forms,但在documentacion我已经find了两种方法来做到这一点。 第一个是使用参考:
var CommentForm = React.createClass({ handleSubmit: function(e) { e.preventDefault(); var author = React.findDOMNode(this.refs.author).value.trim(); var text = React.findDOMNode(this.refs.text).value.trim(); if (!text || !author) { return; } // TODO: send request to the server React.findDOMNode(this.refs.author).value = ''; React.findDOMNode(this.refs.text).value = ''; return; }, render: function() { return ( <form className="commentForm" onSubmit={this.handleSubmit}> <input type="text" placeholder="Your name" ref="author" /> <input type="text" placeholder="Say something..." ref="text" /> <input type="submit" value="Post" /> </form> ); } });
第二个是在React组件中使用状态:
var TodoTextInput = React.createClass({ getInitialState: function() { return { value: this.props.value || '' }; }, render: function() /*object*/ { return ( <input className={this.props.className} id={this.props.id} placeholder={this.props.placeholder} onBlur={this._save} value={this.state.value} /> ); }, _save: function() { this.props.onSave(this.state.value); this.setState({value: '' }); });
如果存在的话,我看不出这两种select的优缺点。 谢谢。
短版:避免参考。
它们对可维护性不利,并且失去了许多所见即所得模型渲染提供的简单性。
你有一个表格。 您需要添加一个重置表单的button。
- 裁判:
- 操纵DOM
- 渲染描述了3分钟前的forms
- 州
- 的setState
- 渲染描述了表单的外观
input中有一个CCV编号字段,应用程序中的其他字段是数字。 现在你需要强制用户只input数字。
- 裁判:
- 添加一个onChange处理程序(是不是我们使用refs来避免这个?)
- 如果不是数字,在onChange中操作dom
- 州
- 你已经有一个onChange处理程序
- 添加一个if语句,如果无效则什么也不做
- 如果渲染将产生不同的结果,则只会调用渲染
呃,没关系,总理要我们做一个红色的阴影,如果它是无效的。
- 裁判:
- 使onChange处理程序只是调用forceUpdate什么的?
- 使渲染输出基于…嗯?
- 我们在哪里得到价值来validation渲染?
- 手动操作元素的className dom属性?
- 我迷路了
- 重写没有参考?
- 从dom中读取渲染,如果我们挂载否则假设有效?
- 州:
- 删除if语句
- 使渲染validation基于this.state
我们需要把控制权交还给家长。 数据现在是道具,我们需要对变化做出反应。
- 裁判:
- 实现componentDidMount,componentWillUpdate和componentDidUpdate
- 手动比较以前的道具
- 用最小的变化来操纵dom
- 嘿! 我们正在实施反应…
- 还有更多,但我的手指受伤了
- 州:
-
sed -e 's/this.state/this.props/' 's/handleChange/onChange/' -i form.js
-
人们认为裁判比保持状态更容易。 这在前20分钟可能是真实的,这之后我的经验是不正确的。 把你的自我置于一个立场,说“是的,我会在5分钟内完成”,而不是“当然,我会重写一些组件”。
我见过一些人引用上面的答案作为“永远不会使用引用”的理由,我想给我(以及其他一些React开发人员所说的)意见。
谈论使用组件实例时,“不要使用refs”情绪是正确的。 这意味着,你不应该使用refs来获取组件实例并调用它们的方法。 这是使用refs的不正确的方法,并且当refs快速向南时。
使用refs的正确(也是非常有用的)方法是当你使用它们从DOM中获得一些值的时候。 例如,如果你有一个input字段附加一个引用到那个input,那么通过引用来获取值就好了。 如果没有这种方式,你需要经过一个相当协调的过程,以保持你的input字段与当地的国家或你的通量存储 – 这似乎是不必要的。
TL; DR一般来说, refs
不符合React的陈述性哲学 ,所以你应该把它们作为最后的手段。 尽可能使用state / props
。
为了理解在哪里使用refs
和state / props
,我们来看一下React所遵循的一些devise原则。
每React 文档关于refs
避免使用refs来处理可以声明的任何事情。
每React的逃生舱devise原则
如果某些对构build应用程序有用的模式很难以声明的方式expression,我们将为其提供一个必要的API。 (他们链接到这里的参考)
这意味着React的团队build议避免refs
和使用state / props
来做任何可以以被动/声明方式完成的事情。
@Tyler McGinnis提供了一个非常好的答案 ,并说明了这一点
使用refs的正确(也是非常有用的)方法是当你使用它们从DOM获得一些值时…
虽然你可以做到这一点,但你会反对React的哲学。 如果你在input中有价值,那么肯定来自state / props
。 为了保持代码的一致性和可预测性,你应该坚持在那里state / props
。 我承认这样的事实,即refs
有时会给你更快的解决scheme,所以如果你做了一个概念certificate, 快速和肮脏是可以接受的。
这给我们留下了几个具体的用例
pipe理焦点,文本select或媒体播放。 触发命令式animation。 与第三方DOM库集成。