为什么ReactClass中的react函数会在表单输入更改事件上重复调用

时间:2016-03-25 15:33:23

标签: javascript reactjs react-bootstrap

我有一个react-bootstrap React Class,其中createList函数在每个表单输入(workDone或hoursAndMinutes)的键输入上被调用。我是反应新手,也许这是正常的行为,但在我看来,它不是,因此我做错了。

var SubjectBox = React.createClass({
  getInitialState(){
    return({
      totalHoursAndMinute:0,
      subject:'',
      workDone:'',
      hoursAndMinutes:'',

    })
  },
  dropDownSelected:function(e){
    this.setState({subject:e.target.value})
  },
  handleChangeToWorkDone(){
    let s = this.refs.workDone.getValue();
    console.log(s);
    this.setState({
      workDone: s
    });
  },
  validateWorkDone:function(){
    let length = this.state.workDone.length;
    if (length >= 10) return 'success';
    else if (length > 5) return 'warning';
    else if (length > 0) return 'error';
  },
  validateHoursAndMinutes(){
    let hm = this.state.hoursAndMinutes.split(':');
    if (hm.length === 2){
      return 'success';
    }else{
      return 'error';
    }
  },
  handleChangeToHoursMinute(){
    var minutes =0;
    let s =this.refs.hoursAndMinutes.getValue();
    let hm =  s.split(':');
    if (hm.length===2){
      var h = parseInt(hm[0].trim());
      var m = parseInt(hm[1].trim());
      if (!m.isNaN){
        var minutes = h*60+m;
      }
    }
    this.setState({
      hoursAndMinutes: s,
      totalMinutes:minutes
    });
  },
  createList: function(){
    console.log("create list function.");
    var list=[];
    for (var i = 0; i < this.props.subjects.length;i++){
      list.push(<option key={i} value={this.props.subjects[i].subject}>{this.props.subjects[i].subject}</option>)
    }
    return list;
  },
  handleSubmit: function(e){
    e.preventDefault();
    console.log(this.state.workDone);
    console.log(this.state.subject);
  },
  render(){
    return(

        <form onSubmit={this.handleSubmit}>
          <Input ref="subjectList" type="select" label="Subject" onChange={this.dropDownSelected}>
            {this.createList()}
          </Input>
          <Input ref="workDone"
            type="text"
            value={this.state.workDone}
            placeholder="What did you do?"
            label="What did you do" help="Input is 10 or more characters."
            bsStyle={this.validateWorkDone()}  hasFeedback
            groupClassName="group-class" labelClassName="label-class"
            onChange={this.handleChangeToWorkDone} />
          <Input ref="hoursAndMinutes"
            type="text" value={this.state.hoursAndMinutes}  placeholder="HH:MM?"
            label="How long did you do it?"  help="Input in hours:minutes, example 1:5 = an hour and five minutes."
            bsStyle={this.validateHoursAndMinutes()}  hasFeedback
            groupClassName="group-class"
            labelClassName="label-class"   onChange={this.handleChangeToHoursMinute} />
          <Button type="submit" bsStyle="success">Submit</Button>
        </form>

    )
  }
});

2 个答案:

答案 0 :(得分:3)

之所以发生这种情况,是因为您在handleChangeToWorkDonehandleChangeToWorkDone setState中使用了re-render

  除非有条件,否则

setState()将始终触发重新渲染   渲染逻辑在shouldComponentUpdate()中实现。如果可变的话   正在使用对象,逻辑无法实现   shouldComponentUpdate(),仅在新状态时调用setState()   与以前的状态不同,将避免不必要的重新渲染。

答案 1 :(得分:0)

在React Js中,HTML / DOM始终只是React Component状态的表示。

每当有onChange或onBlur或任何事件时,如果更改了React Component的状态(使用setState func),则重新渲染ReactJs组件(使用Render func)。

只有当React Js组件的状态发生变化时,才能使用您键入的值更新UI。因此,这是React Js中的预期行为。