154

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. 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.

4

13 回答 13

174

我建议坚持使用 Elements 等标准 HTML 属性nameinput识别您的输入。此外,您不需要将“总计”作为单独的值保留在状态中,因为它可以通过在您的状态中添加其他值来组合:

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'));
于 2014-01-09T21:43:55.117 回答
107

您可以使用该.bind方法预先构建该handleChange方法的参数。它会是这样的:

  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'));

(我也在total渲染时进行了计算,因为这是推荐的做法。)

于 2014-03-02T16:47:54.957 回答
41

事件onChange冒泡......所以你可以做这样的事情:

// A sample form
render () {
  <form onChange={setField}>
    <input name="input1" />
    <input name="input2" />
  </form>
}

您的 setField 方法可能如下所示(假设您使用的是 ES2015 或更高版本:

setField (e) {
  this.setState({[e.target.name]: e.target.value})
}

我在几个应用程序中使用了类似的东西,它非常方便。

于 2016-03-14T20:33:19.107 回答
12

已弃用的解决方案

valueLink/checkedLink已从核心 React中弃用,因为它使一些用户感到困惑。如果您使用最新版本的 React,此答案将不起作用。但如果你喜欢它,你可以通过创建自己的Input组件轻松地模拟它

旧答案内容:

使用 React 的 2-way 数据绑定助手可以更轻松地实现您想要实现的目标。

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'));

容易吧?

http://facebook.github.io/react/docs/two-way-binding-helpers.html

你甚至可以实现自己的 mixin

于 2014-01-25T15:31:01.183 回答
7

你也可以这样做:

...
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>
    )
}
于 2017-01-08T19:17:12.680 回答
5

如果有人在寻找功能组件示例,

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>
 );
}
于 2021-04-21T14:29:02.777 回答
4

您可以使用一个React名为的特殊属性ref,然后onChange使用React'sgetDOMNode()函数匹配事件中的真实 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>
  ...
}
于 2014-05-01T20:38:55.403 回答
0

@Vigril Disgr4ce

当涉及到多字段表单时,使用 React 的关键特性是有意义的:组件。

在我的项目中,我创建了 TextField 组件,它至少需要一个 value 属性,它负责处理输入文本字段的常见行为。这样您就不必担心在更新值状态时跟踪字段名称。

[...]

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} />;
}

[...]
于 2014-02-27T01:24:03.660 回答
0

状态对象

const [values, setValues] = useState({
    email: "",
    password: "",
  });

改变状态的函数

const handleChange = name => event => {
    setValues({ ...values, [name]: event.target.value });
 };

在使用“名称”更改输入时调用上述函数

<input 
onChange={handleChange("email")} 
value={email}
className="form-control"
type="email"
       />
于 2021-04-27T08:37:28.187 回答
0

您可以input通过创建一个单独的InputField组件来管理单个input. 例如,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} />)
  }
})

现在input可以在此组件的单独实例中跟踪每个值,InputField而无需在父状态中创建单独的值来监视每个子组件。

于 2016-12-13T11:52:22.240 回答
0

我将为这个问题提供非常简单的解决方案。假设我们有两个输入usernamepassword,但我们希望我们的句柄简单通用,所以我们可以重用它而不编写样板代码。

一、我们的形式:

                <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.我们的构造函数,我们想保存我们的usernameand password,所以我们可以很容易地访问它们:

constructor(props) {
    super(props);
    this.state = {
        username: '',
        password: ''
    };

    this.onSubmit = this.onSubmit.bind(this);
    this.onChange = this.onChange.bind(this);
}

III.只有一个onChange事件的有趣且“通用”的句柄是基于此:

onChange(event) {
    let inputName = event.target.name;
    let value = event.target.value;

    this.setState({[inputName]:value});


    event.preventDefault();
}

让我解释:

1.当检测到变化时onChange(event)调用

2.然后我们得到字段的name参数及其值:

let inputName = event.target.name; ex: username

let value = event.target.value; ex: itsgosho

3.基于 name 参数,我们从构造函数中的状态中获取我们的值,并使用该值更新它:

this.state['username'] = 'itsgosho'

4.这里要注意的关键是该字段的名称必须与我们在状态中的参数匹配

希望我以某种方式帮助了某人:)

于 2019-09-07T22:09:37.443 回答
0

您的状态键应与输入字段的名称相同。然后你可以在handleEvent方法中做到这一点;

this.setState({
        [event.target.name]: event.target.value
});
于 2020-04-25T19:04:16.730 回答
-1

嗨,改进了ssorallen 的答案。您不需要绑定函数,因为您可以在没有它的情况下访问输入。

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'));
于 2016-01-20T09:19:11.200 回答