我正在尝试在React中做一些在任何其他框架中都非常简单的事情:我想从表单中收集一堆值。
以前我用Backbone View做过这种事情,这很简单:
readFormValues: function() {
this.data.foo = this.$('[name="foo"]').val();
this.data.bar = this.$('[name="bar"]:checked').val();
});
但在React中我似乎无法找到一种简单的方法。看来我唯一的选择就是......
注意:格式化的道歉:代码块和列表不能很好地协同工作: - (
完全绕过React并使用jQuery + e.target
访问表单:
handleSubmit: function(e) {
var $form = $(e.target).parents('form:first');
this.data.foo = $form.find('[name="foo"]);
},
render: function() {
return <form onSubmit="handleSubmit"><input name="foo"/></form>;
}
这很有效,而且很简单,但感觉就像我在使用React时绕过React并使用JQuery。
为每个表单控件提供回调:
handleFooClick: function(e) {
this.data.foo = event.target.value;
},
render: function() {
return <form><input name="foo" onChange="handleFooChange"/></form>;
}
这似乎是React / Flux的方式,但感觉就像一堆疯狂的不必要的工作。在我的Backbone示例中,每个表单控件只需要一行,但是使用这种方法我构建的每个最后一个控件都必须有自己的onChange处理程序(我必须在处理它时将该处理程序挂钩到每个元素)。
编辑:此方法的另一个缺点是回调内部this.props
和this.state
不会指向我的表单控件的props / state(它将指向输入的道具/州)。这意味着我不仅需要为每个输入编写一个处理程序,并在渲染时将该回调添加到每个输入,但我还必须将我的数据对象传递给每个输入!
使用refs:
handleSubmit: function(e) {
this.state.data.foo = this.refs.foo.value;
},
render: function() {
return <form><input ref="foo"/></form>;
}
这似乎是一个更理智的解决方案,因为我只需要为每个表单控件添加一个“ref”属性,然后我就可以像在Backbone中一样轻松地读取数据。但是,所有的React文档都表明使用refs的方法是错误的(所有使用refs的例子都涉及向控件发送信号,例如“专注于此输入”,而不是从控件中读取数据)。
我觉得必须有一种“React-ive”方式来访问我的表格数据,这种表格数据并非不必要的复杂,但我没有看到它,因为我不太了解React。如果任何React专家能够解释我所缺少的东西,我将非常感激。
答案 0 :(得分:3)
首先,jQuery是一种不必要的依赖,它不是最干净的选择,所以让我们排除它。
接下来,裁判有灵活性问题。有关详细信息,请参阅此answer。除了最简单的情况之外,让我们的规则适用于所有情况。
留下选项#2 - Facebook称之为controlled components。受控组件很棒,因为它们涵盖了所有用例(例如keyup上的验证)。虽然代码不多,但如果您不想为每个表单元素添加简单的更改处理程序,则可以使用bind
为所有元素使用一个更改处理程序。像这样:
handleChange: function(fieldName, e) {
console.log("field name", fieldName);
console.log("field value", e.target.value);
// Set state or use external state.
},
render: function() {
var someValue = this.state.someValue; // Or a prop is using external state
return (
<div>
<input
name="someName"
value={someValue}
onChange={this.handleChange.bind(this, "someName")} />
</div>
)
}
或者更清洁的方式,请参阅此answer。
答案 1 :(得分:1)
您可以使用ReactLink
在反应组件和州之间创建双向绑定。
此处描述:https://facebook.github.io/react/docs/two-way-binding-helpers.html
答案 2 :(得分:1)
对于一个较小的项目,我一直在使用单个onChange回调所有输入 - 就像这样......
HandleClick(event) {
let values = this.state.values;
values[event.target.name] = event.target.value;
this.setState({values});
}
这要求您为输入命名与命名状态属性相同,但我非常喜欢。然后,将状态存储的值提供给输入的value属性,然后全部设置 - 所有表单状态都存储在一个具有单个处理函数的位置。
当然还有更多可扩展的方式 - 我只是在阅读一个看起来很有趣的反应框架。这是一个教程: http://christianalfoni.github.io/javascript/2014/10/22/nailing-that-validation-with-reactjs.html
希望有所帮助
丹
答案 3 :(得分:1)
这是我处理表单中所有字段的方式。
var My_Field=React.createClass({
_onChange: function(evt) {
var e=this.props.parent_form;
if (e) {
e.setState({email: evt.target.value});
}
},
render: function() {
return (
<input type="text" name={this.props.name} placeholder={this.props.label} onChange={this._onChange}/>
);
}
});
var My_Form=React.createClass({
getInitialState: function() {
return {
email: "",
};
},
_onSubmit: function(evt) {
evt.preventDefault();
alert(this.state.email);
},
render: function() {
return (
<form onSubmit={this._onSubmit}>
<My_Field name="email" label="Email" parent_form={this}/>
<input type="submit" value="Submit"/>
</form>
);
}
});
答案 4 :(得分:0)
您只需使用一个功能即可阅读表单数据。
类SignUp扩展了Component {
constructor(){
super();
this.handleLogin = this.handleLogin.bind(this);
}
handleLogin(e){
e.preventDefault();
const formData = {};
for(const field in this.refs){
formData[field] = this.refs[field].value;
}
console.log('-->', formData);
}
render(){
return (
<form onSubmit={this.handleLogin} className="form-horizontal">
<div className="form-group text-left">
<label className="control-label col-sm-2">Name:</label>
<div className="col-sm-10">
<input ref="name" type="text" className="form-control" name="name" placeholder="Enter name" />
</div>
</div>
<div className="form-group text-left">
<label className="control-label col-sm-2">Email:</label>
<div className="col-sm-10">
<input ref="email" type="email" className="form-control" name="email" placeholder="Enter email" />
</div>
</div>
<div className="form-group text-left">
<label className="control-label col-sm-2">Password:</label>
<div className="col-sm-10">
<input ref="password" type="password" className="form-control" name="password" placeholder="Enter password" />
</div>
</div>
<div className="form-group text-left">
<div className="col-sm-offset-2 col-sm-10">
<button type="submit" className="btn btn-primary btn-block">Signup</button>
</div>
</div>
</form>
)
} }export default SignUp;
答案 5 :(得分:0)
使用React
的{{1}}:最快,最简单的方法:
useState()