[英]React.js: Identifying different inputs with one onChange handler
Curious what the right way to approach this is:好奇解决这个问题的正确方法是什么:
var Hello = React.createClass({
getInitialState: function() {
return {total: 0, input1:0, input2:0};
},
render: function() {
return (
<div>{this.state.total}<br/>
<input type="text" value={this.state.input1} onChange={this.handleChange} />
<input type="text" value={this.state.input2} onChange={this.handleChange} />
</div>
);
},
handleChange: function(e){
this.setState({ ??? : e.target.value});
t = this.state.input1 + this.state.input2;
this.setState({total: t});
}
});
React.renderComponent(<Hello />, document.getElementById('content'));
Obviously you could create separate handleChange functions to handle each different input, but that's not very nice.显然,您可以创建单独的 handleChange 函数来处理每个不同的输入,但这不是很好。 Similarly you could create a component just for an individual input, but I wanted to see if there's a way to do it like this.同样,您可以仅为单个输入创建一个组件,但我想看看是否有办法做到这一点。
I suggest sticking to standard HTML attributes like name
on input
Elements to identify your inputs.我建议坚持使用标准的 HTML 属性,例如input
元素上的name
来标识您的输入。 Also, you don't need to keep "total" as a separate value in state because it is composable by adding other values in your state:此外,您不需要在 state 中将“total”作为单独的值保留,因为它可以通过在您的 state 中添加其他值来组合:
var Hello = React.createClass({
getInitialState: function() {
return {input1: 0, input2: 0};
},
render: function() {
const total = this.state.input1 + this.state.input2;
return (
<div>{total}<br/>
<input type="text" value={this.state.input1} name="input1" onChange={this.handleChange} />
<input type="text" value={this.state.input2} name="input2" onChange={this.handleChange} />
</div>
);
},
handleChange: function(e) {
this.setState({[e.target.name]: e.target.value});
}
});
React.renderComponent(<Hello />, document.getElementById('content'));
You can use the .bind
method to pre-build the parameters to the handleChange
method.您可以使用.bind
方法预先构建handleChange
方法的参数。 It would be something like:它会是这样的:
var Hello = React.createClass({
getInitialState: function() {
return {input1:0,
input2:0};
},
render: function() {
var total = this.state.input1 + this.state.input2;
return (
<div>{total}<br/>
<input type="text" value={this.state.input1}
onChange={this.handleChange.bind(this, 'input1')} />
<input type="text" value={this.state.input2}
onChange={this.handleChange.bind(this, 'input2')} />
</div>
);
},
handleChange: function (name, e) {
var change = {};
change[name] = e.target.value;
this.setState(change);
}
});
React.renderComponent(<Hello />, document.getElementById('content'));
(I also made total
be computed at render time, as it is the recommended thing to do.) (我还在渲染时计算了total
,因为这是推荐的做法。)
The onChange
event bubbles... So you can do something like this: onChange
事件冒泡......所以你可以做这样的事情:
// A sample form
render () {
<form onChange={setField}>
<input name="input1" />
<input name="input2" />
</form>
}
And your setField method might look like this (assuming you're using ES2015 or later:您的 setField 方法可能如下所示(假设您使用的是 ES2015 或更高版本:
setField (e) {
this.setState({[e.target.name]: e.target.value})
}
I use something similar to this in several apps, and it's pretty handy.我在几个应用程序中使用了类似的东西,它非常方便。
valueLink/checkedLink
are deprecated from core React, because it is confusing some users. valueLink/checkedLink
从核心 React 中被弃用,因为它让一些用户感到困惑。 This answer won't work if you use a recent version of React.如果您使用最新版本的 React,此答案将不起作用。 But if you like it, you can easily emulate it by creating your own Input
component但是如果你喜欢它,你可以通过创建你自己的Input
组件来轻松地模仿它
What you want to achieve can be much more easily achieved using the 2-way data binding helpers of React.使用 React 的 2 路数据绑定助手可以更轻松地实现您想要实现的目标。
var Hello = React.createClass({
mixins: [React.addons.LinkedStateMixin],
getInitialState: function() {
return {input1: 0, input2: 0};
},
render: function() {
var total = this.state.input1 + this.state.input2;
return (
<div>{total}<br/>
<input type="text" valueLink={this.linkState('input1')} />;
<input type="text" valueLink={this.linkState('input2')} />;
</div>
);
}
});
React.renderComponent(<Hello />, document.getElementById('content'));
Easy right?容易吧?
http://facebook.github.io/react/docs/two-way-binding-helpers.html http://facebook.github.io/react/docs/two-way-binding-helpers.html
You can even implement your own mixin你甚至可以实现你自己的 mixin
You can also do it like this:你也可以这样做:
...
constructor() {
super();
this.state = { input1: 0, input2: 0 };
this.handleChange = this.handleChange.bind(this);
}
handleChange(input, value) {
this.setState({
[input]: value
})
}
render() {
const total = this.state.input1 + this.state.input2;
return (
<div>
{total}<br />
<input type="text" onChange={e => this.handleChange('input1', e.target.value)} />
<input type="text" onChange={e => this.handleChange('input2', e.target.value)} />
</div>
)
}
You can use a special React
attribute called ref
and then match the real DOM nodes in the onChange
event using React
's getDOMNode()
function:您可以使用称为ref
的特殊React
属性,然后使用React
的getDOMNode()
函数匹配onChange
事件中的真实 DOM 节点:
handleClick: function(event) {
if (event.target === this.refs.prev.getDOMNode()) {
...
}
}
render: function() {
...
<button ref="prev" onClick={this.handleClick}>Previous question</button>
<button ref="next" onClick={this.handleClick}>Next question</button>
...
}
If anyone looking for Functional Component Example,如果有人在寻找功能组件示例,
import React, { useState } from "react";
export default function Exapmle() {
const [userState, setUserState] = useState({
firstName: "",
lastName: ""
})
const handleChange = (e)=>{
const value = e.target.value;
setUserState({
...userState,
[e.target.name]: value
});
}
return (
<form>
<label>
First name
<input type="text" name="firstName" value={userState.firstName}
onChange={handleChange}
/>
</label>
<label>
Last name
<input type="text" name="lastName" value={userState.lastName}
onChange={handleChange}
/>
</label>
</form>
);
}
@Vigril Disgr4ce @Vigril Disgr4ce
When it comes to multi field forms, it makes sense to use React's key feature: components.当涉及到多字段表单时,使用 React 的关键特性:组件是有意义的。
In my projects, I create TextField components, that take a value prop at minimum, and it takes care of handling common behaviors of an input text field.在我的项目中,我创建了 TextField 组件,这些组件至少带有一个 value 属性,它负责处理输入文本字段的常见行为。 This way you don't have to worry about keeping track of field names when updating the value state.这样您就不必担心在更新值状态时跟踪字段名称。
[...]
handleChange: function(event) {
this.setState({value: event.target.value});
},
render: function() {
var value = this.state.value;
return <input type="text" value={value} onChange={this.handleChange} />;
}
[...]
You can track the value of each child input
by creating a separate InputField
component that manages the value of a single input
.您可以通过创建一个单独的InputField
组件来管理单个input
的值,从而跟踪每个子input
的值。 For example the InputField
could be:例如InputField
可以是:
var InputField = React.createClass({
getInitialState: function () {
return({text: this.props.text})
},
onChangeHandler: function (event) {
this.setState({text: event.target.value})
},
render: function () {
return (<input onChange={this.onChangeHandler} value={this.state.text} />)
}
})
Now the value of each input
can be tracked within a separate instance of this InputField
component without creating separate values in the parent's state to monitor each child component.现在,可以在此InputField
组件的单独实例中跟踪每个input
的值,而无需在父组件的状态中创建单独的值来监视每个子组件。
I will provide really simple solution to the problem.我将为这个问题提供非常简单的解决方案。 Suppose we have two inputs username
and password
,but we want our handle to be easy and generic ,so we can reuse it and don't write boilerplate code.假设我们有两个输入username
和password
,但我们希望我们的句柄简单通用,这样我们就可以重用它并且不编写样板代码。
I.Our form:一、我们的形式:
<form>
<input type="text" name = "username" onChange={this.onChange} value={this.state.username}/>
<input type="text" name = "password" onChange={this.onChange} value={this.state.password}/>
<br></br>
<button type="submit">Submit</button>
</form>
II.Our constructor ,which we want to save our username
and password
,so we can access them easily: II.我们的构造函数,我们想保存我们的username
和password
,以便我们可以轻松访问它们:
constructor(props) {
super(props);
this.state = {
username: '',
password: ''
};
this.onSubmit = this.onSubmit.bind(this);
this.onChange = this.onChange.bind(this);
}
III.The interesting and "generic" handle with only one onChange
event is based on this: III.只有一个onChange
事件的有趣且“通用”的句柄基于此:
onChange(event) {
let inputName = event.target.name;
let value = event.target.value;
this.setState({[inputName]:value});
event.preventDefault();
}
Let me explain:让我解释:
1.When a change is detected the onChange(event)
is called 1.当检测到变化时,调用onChange(event)
2.Then we get the name parameter of the field and its value: 2.然后我们获取字段的名称参数及其值:
let inputName = event.target.name; ex: username
let value = event.target.value; ex: itsgosho
3.Based on the name parameter we get our value from the state in the constructor and update it with the value: 3.基于 name 参数,我们从构造函数中的状态中获取我们的值并使用该值更新它:
this.state['username'] = 'itsgosho'
4.The key to note here is that the name of the field must match with our parameter in the state 4.这里要注意的关键是field的名字必须和我们在state中的参数相匹配
Hope I helped someone somehow :)希望我以某种方式帮助了某人:)
The key of your state should be the same as the name of your input field.您状态的键应该与输入字段的名称相同。 Then you can do this in the handleEvent method;然后你可以在 handleEvent 方法中做到这一点;
this.setState({
[event.target.name]: event.target.value
});
state object状态对象
const [values, setValues] = useState({
email: "",
password: "",
});
function that change state改变状态的函数
const handleChange = name => event => {
setValues({ ...values, [name]: event.target.value });
};
call above function on onchange of input with "name"使用“名称”更改输入时调用上述函数
<input
onChange={handleChange("email")}
value={email}
className="form-control"
type="email"
/>
Hi have improved ssorallen answer.嗨,已经改进了ssorallen 的答案。 You don't need to bind function because you can access to the input without it.您不需要绑定函数,因为您可以在没有它的情况下访问输入。
var Hello = React.createClass({
render: function() {
var total = this.state.input1 + this.state.input2;
return (
<div>{total}<br/>
<input type="text"
value={this.state.input1}
id="input1"
onChange={this.handleChange} />
<input type="text"
value={this.state.input2}
id="input2"
onChange={this.handleChange} />
</div>
);
},
handleChange: function (name, value) {
var change = {};
change[name] = value;
this.setState(change);
}
});
React.renderComponent(<Hello />, document.getElementById('content'));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.