在 ReactJS 中获取表单输入法的值以进行可能的算术运算

Grabbing the value of a form input method for a possible arithmetic operation in ReactJS

这是我多年后的第一个问题,如果我违反了任何 forum/platform 规则,请原谅我。

我正在尝试构建一个 CGPA 计算器,所以我在根据用户输入更改更新变量时遇到问题。

我是初学者,所以我的代码和描述可能很水。我猜问题出在我的 handleChange 方法上,因为每次我进行输入时(我现在正在使用 courseInput 进行测试),应用程序崩溃并出现错误:

TypeError: Cannot read property 'setState' of undefined

请哪位详细解释一下。

实际上我已经尝试了很多谷歌搜索,但我的代码似乎没有任何问题。

import React, { Component } from 'react';
  import './App.css';
class App extends Component {

    constructor(props) {
    super(props);
    // this.courseInput = React.createRef();
    this.state = {
      courseInput: [],
        courseCode: '',
        courseUnit: [0],
        courseGrade: [],
      totalPoint: 0,
      totalUnit: 0,
      newCourseInput: <form>
        <input onChange={this.handleChange} type="text" placeholder='COURSE CODE' value={this.courseCode} />
        {/* <input type="number" placeholder='COURSE UNIT' ref={this.courseUnit} value={this.courseUnit} />
        <input type="number" placeholder='COURSE GRADE' ref={this.courseGrade} value={this.courseGrade} /> */}
      </form>
    };
    this.createAnother = this.createAnother.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }

  // THIS createAnother TAKES THE CURRENT STATE OF courseInput AND CONCATENATES IT WITH THE newCourseInput TO MAKE LIST
  createAnother() {
    var courseInput = this.state.courseInput.concat(this.state.newCourseInput)
    this.setState({ courseInput })
  }

  handleChange(event) {
    var updatedCourseCode = event.target.value;
    this.setState({ courseInput: updatedCourseCode }, () => console.log(this.state))

  }

  
  render() {
    // console.log(this);
    // var courseInput = this.state.courseInput;
  return(
    <div>
      <header className="App-header">
        <p>
         THIS IS A CGPA CALCULATOR
        </p>
      </header>
        {/* MAP FUNCTION LOOPS THROUGH THE ARRAY courseInput AND PRINTS OUT THE CODE UNIT AND GRADE IN IN ORDERED LIST */}
        <ol>
        {this.state.courseInput.map((courseInput, index) => 
            <li key={index}>{courseInput}</li>
          
            )}
        </ol>
      
      {/* THIS TRIGGERS AN EVENT HANDLER createAnother LOCATED UP THERE */}
        <button onClick={this.createAnother} >ADD ANOTHER COURSE</button>
      
  </div>
  );
  }
  }
  
  
  export default App;

在 handleChange 中使用箭头函数而不是常规函数:

class A {
 handleChange(event){
this //  the keyword "this" refer to the function handleChange

}
}

class A {
 handleChange =(event)=>{
this // the keyword "this" refer to the class A

}
}

常规函数和箭头函数的区别:read-me

您没有在

input 标签中正确地将 this 绑定到 handleChange
<input onChange={this.handleChange} type="text" placeholder='COURSE CODE' value={this.courseCode} />

您应该将 onChange 函数更新为 onChange={this.handleChange.bind(this)}

this实际上是调用函数时进行的绑定,它引用的内容完全由调用函数的调用位置决定,而不是声明位置。 https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/this%20%26%20object%20prototypes/ch2.md

上有更多内容

您不应在您的状态中存储 jsx 元素,而应仅存储必要的数据以便稍后在需要时呈现这些元素。你也有错误(你试图将字符串分配给数组的 courseInput)。

import React, { Component } from "react";
// import './App.css';
class App extends Component {
  constructor(props) {
    super(props);
    // this.courseInput = React.createRef();
    this.state = {
      courseInput: [],
      courseCode: "",
      courseUnit: [0],
      courseGrade: [],
      totalPoint: 0,
      totalUnit: 0,
    };
  }

  // THIS createAnother TAKES THE CURRENT STATE OF courseInput AND CONCATENATES IT WITH THE newCourseInput TO MAKE LIST
  createAnother = () => {
    var courseInput = this.state.courseInput.concat({
      id: this.state.courseInput.length,
      value: "",
    });
    this.setState({ courseInput });
  };

  handleCourseChange = (value, id) => {
    const newCourseInputs = [...this.state.courseInput];
    console.log(newCourseInputs);
    console.log(value, id);
    let courseToChange = newCourseInputs.find((c) => c.id == id);
    courseToChange.value = value;
    this.setState({ courseInput: newCourseInputs });
  };

  render() {
    // console.log(this);
    // var courseInput = this.state.courseInput;
    console.log(this.state.courseInput);
    return (
      <div>
        <header className="App-header">
          <p>THIS IS A CGPA CALCULATOR</p>
        </header>
        {/* MAP FUNCTION LOOPS THROUGH THE ARRAY courseInput AND PRINTS OUT THE CODE UNIT AND GRADE IN IN ORDERED LIST */}
        <ol>
          {this.state.courseInput.map((courseInput, index) => (
            <li key={index}>
              <input
                onChange={(e) =>
                  this.handleCourseChange(e.target.value, courseInput.id)
                }
                type="text"
                placeholder="COURSE CODE"
                value={courseInput.value}
              />
            </li>
          ))}
        </ol>
        {/* THIS TRIGGERS AN EVENT HANDLER createAnother LOCATED UP THERE */}

        <button onClick={this.createAnother}>ADD ANOTHER COURSE</button>
      </div>
    );
  }
}

export default App;

此代码可能会按您的预期运行。