handleSubmit和onChange handleSubmit导致setState错误或无法输入字符

时间:2017-07-29 14:58:06

标签: javascript reactjs ecmascript-6

我是React的新手,似乎遇到了handleSubmit和onChange的错误。它正在正常处理三个事件(我最终想要问你一个问题,然后一个条件语句带你到下一个问题)。

当我尝试解决此问题时,我遇到了三个不同的错误。我有handleChange影响三个不同文本输入的onChange。如果我在输入上试试这个

onChange={this.handleChange.bind(this, 'input1')}

handleChange为:

      handleChange(name, event) {
    const change = {};
    change[name] = event.target.value;
    this.setState(change);
    // this.setState({ value: event.target.value });
    event.preventDefault();
  }

我无法在文本输入中输入任何内容,因为它似乎已冻结。如果我将订单更改为

handleChange(event, name)我收到错误:

TypeError: Cannot read property 'value' of undefined

如果我尝试这种方式(下面)它可以工作但是当我在任何输入中输入文本时,它会同时改变所有这些输入。我不知道如何解决这个问题。我想做的是能够在多个文本输入中单独输入。

另外,React.js中的条件对我来说仍然有点困难,我不知道如何在第一个输入被回答和提交的地方写出来,它会转到下一个。

以下是正在运行的代码(有点),但同时在所有三个输入中进行更新

    import React, { Component } from 'react';
    import styled from 'styled-components';
    import Crawler from './crawler';
    
    const NextQuestion = styled.div`
      position: absolute;
      color: white;
      display: block;
      margin-top: 108px;
    `;
    
    class NameForm extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          value: 'enter proper name',
          value2: 'noun',
          value3: 'enter another proper name',
          newValue: '',
          submitted: false,
          input1: 0,
          input2: 0,
          input3: 0
        };
    
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
      }
    
      handleChange(event) {
        this.setState({
          value: event.target.value,
          value2: event.target.value2,
          value3: event.target.value3
        });
        event.preventDefault();
      }
    
      handleSubmit(event) {
        event.preventDefault();
        console.log('submit worked!!!');
        let toggle = this.state.visable;
        this.setState({ visable: !toggle });
      }
    
      render() {
        const divStyle = {
          marginTop: '50px',
          color: 'white',
          top: '25px',
          position: 'absolute'
        };
        let question = null;
        const show = this.state.visable;
        if (show) {
          question = (
            <div>
              <Crawler
                properName1={this.state.value}
                noun1={this.state.value2}
                properName2={this.state.value3}
              />
            </div>
          );
        }
        return (
          <div>
            <div style={divStyle}>
              <form onSubmit={this.handleSubmit}>
                <label>
                  Proper Name:
                  <input
                    name="input1"
                    type="text"
                    value={this.state.value}
                    onChange={this.handleChange}
                  />
                </label>
                <label>
                  Noun:
                  <input
                    name="input2"
                    type="text"
                    value={this.state.value2}
                    onChange={this.handleChange}
                  />
                </label>
                <label>
                  Another Proper Name:
                  <input
                    name="input3"
                    type="text"
                    value={this.state.value3}
                    onChange={this.handleChange}
                  />
                </label>
                <input type="submit" value="Submit" />
              </form>
            </div>
            <NextQuestion>
              {question}
            </NextQuestion>
          </div>
        );
      }
    }
    
    export default NameForm;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.min.js"></script>

请帮忙。

1 个答案:

答案 0 :(得分:2)

首先,function.prototype.bind首先传递绑定参数,然后传递其他参数。在接受争论并开展工作时,请记住这一点。以下是对function.prototype.bind()

的引用

其次,我喜欢这种方法,你希望维护一个函数handleChange来更新所有输入的状态,但你已经错误地实现了它。我为每个输入做了单独的onChange函数调用,并将它们全部绑定到同一个函数handleChange,并在ES6 function binding的帮助下传递了一个额外的参数。并且您无需将this显式绑定到您的函数,因为ES6 Fat Arrows会处理此问题。看看ES6 arrow bindings

第三,我更新了handleChange函数,只更新了更改的值,避免了其他输入值的不必要状态更改。

我已经提供了更正的解决方案,希望这应该对你有用。

import React, { Component } from 'react';
import styled from 'styled-components';
import Crawler from './crawler';

const NextQuestion = styled.div`
  position: absolute;
  color: white;
  display: block;
  margin-top: 108px;
`;

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value1: 'enter proper name',
      value2: 'noun',
      value3: 'enter another proper name',
      newValue: '',
      submitted: false,
      input1: 0,
      input2: 0,
      input3: 0
    };

    this.handleFirstChange = (event) =>   this.handleChange(event, 'value1');
    this.handleSecondChange = (event) => this.handleChange(event, 'value2');
    this.handleThirdChange = (event) => this.handleChange(event, 'value3');
    this.handleSubmit = (event) => this._handleSubmit(event);
  }

  handleChange(event, type) {
    let newState = {};
    newState[type] = event.target.value;
    this.setState(newState);
  }

  _handleSubmit(event) {
    event.preventDefault();
    console.log('submit worked!!!');
    let toggle = this.state.visable;
    this.setState({ visable: !toggle });
  }

  render() {
    const divStyle = {
      marginTop: '50px',
      color: 'white',
      top: '25px',
      position: 'absolute'
    };
    let question = null;
    const show = this.state.visable;
    if (show) {
      question = (
        <div>
          <Crawler
            properName1={this.state.value1}
            noun1={this.state.value2}
            properName2={this.state.value3}
          />
        </div>
      );
    }
    return (
      <div>
        <div style={divStyle}>
          <form onSubmit={this.handleSubmit}>
            <label>
              Proper Name:
              <input
                name="input1"
                type="text"
                value={this.state.value1}
                onChange={this.handleFirstChange}
              />
            </label>
            <label>
              Noun:
              <input
                name="input2"
                type="text"
                value={this.state.value2}
                onChange={this.handleSecondChange}
              />
            </label>
            <label>
              Another Proper Name:
              <input
                name="input3"
                type="text"
                value={this.state.value3}
                onChange={this.handleThirdChange}
              />
            </label>
            <input type="submit" value="Submit" />
          </form>
        </div>
        <NextQuestion>
          {question}
        </NextQuestion>
      </div>
    );
  }
}

export default NameForm;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.min.js"></script>