【问题标题】:Event-handler is not executing calculation事件处理程序未执行计算
【发布时间】:2019-10-24 09:11:24
【问题描述】:

我目前正在学习 typescript/react,并且正在开发一个小程序来练习我的技能。

我现在卡住了。

import React, { Component } from "react";

interface triangleInfo {
  base: number;
  height: number;
  area: number;
  error: string;
}

export default class triangleArea extends React.Component<triangleInfo> {
  constructor(props: triangleInfo) {
    super(props);

    //initializing variables to undefined
    this.handleChange = this.handleChange.bind(this);

    this.state = {
      base: 0,
      height: 0,
      area: undefined,
      error: ""
    };
  }

  //Handling change of input Base and HEIGHT

  handleChange = (input: "base" | "height", value) => {
    this.setState({
      [input]: value
    });
  };

  //getArea function to calculate Area
  getArea = triangleInfo => {
    triangleInfo.preventDefault();

    const { base, height } = this.props;

    if (base > 0 && height > 0) {
      this.setState({
        area: (base * height) / 2
      });
    } else {
      this.setState({
        base: undefined,
        height: undefined,
        area: undefined,
        error: "Please enter the values correctly."
      });
    }
  };

  render() {
    const { base, height } = this.props;

    let resultMarkup;

    //If error is true, prints message to the user
    if (this.props.base < 0 && this.props.height < 0) {
      resultMarkup = (
        <p className="error-m">
          There is an error, please enter positive numbers!
        </p>
      );
    }
    //if erorr is false it will print the current state of the pokemon interface.
    else {
      resultMarkup = (
        //Div with all the information retrieve from the pokemon API

        <div>
          <p>The base of the triangle is: {this.props.base}</p>
          <p>The height of the triangle is: {this.props.height}</p>
          <p>The area of the triangle is: {this.props.area}</p>
        </div>
      );
    }
    return (
      //...
      <div>
        <form onSubmit={this.getArea}>
          <p>Calculate the base of a triangle!</p>
          <input
            type="text"
            id="base"
            placeholder="base"
            value={base}
            onChange={e => this.handleChange("base", e.target.value)}
          />
          <input
            type="text"
            id="height"
            placeholder="height"
            value={height}
            onChange={e => this.handleChange("height", e.target.value)}
          />
          <button type="submit">Get Area</button>

          {resultMarkup}
        </form>
      </div>
      //...
    );
  }
}

我希望用户输入任何值,然后计算新区域,但我不知道如何动态进行。

【问题讨论】:

  • 请发布一些代码,而不仅仅是沙箱。
  • 很抱歉,我觉得如果我的程序是如何工作的,用视觉表示会更好。
  • 别担心,我已经更新了您的问题,并在下面为您提供了答案。另请参阅沙盒 :)

标签: reactjs typescript components


【解决方案1】:

问题是您使用来自props 而不是状态的值。当用户填写表单时,您正在更新 handleChange() 设置中正确的组件状态。但是,在 getArea() 中,您使用的是 prop-values,其中不包括用户提供的数据。

https://codesandbox.io/s/somemath-1il3r

import React, { Component } from "react";

interface triangleInfo {
  base: number;
  height: number;
  area: number;
  error: string;
}

interface MyComponentState {
  base: number;
  height: number;
  area: number;
  error: string;
}

export default class triangleArea extends React.Component<
  triangleInfo,
  MyComponentState
> {
  constructor(props: triangleInfo) {
    super(props);

    //initializing variables to undefined
    this.state = {
      base: 0,
      height: 0,
      area: 0,
      error: ""
    };
    this.handleChange = this.handleChange.bind(this);
  }

  //Handling change of input Base and HEIGHT
  handleChange = e => {
    this.setState({ [e.target.name]: e.target.value } as any);
  };

  //getArea function to calculate Area
  getArea = triangleInfo => {
    triangleInfo.preventDefault();

    const { base, height } = this.state;

    if (base > 0 && height > 0) {
      this.setState({
        area: (base * height) / 2,
        error: ""
      });
    } else {
      this.setState({
        base: 0,
        height: 0,
        area: 0,
        error: "Please enter the values correctly."
      });
    }
  };

  render() {
    const { base, height, area, error } = this.state;

    let resultMarkup;

    //If error is true, prints message to the user
    if (this.props.base < 0 && this.props.height < 0) {
      resultMarkup = (
        <p className="error-m">
          There is an error, please enter positive numbers!
        </p>
      );
    }
    //if erorr is false it will print the current state of the pokemon interface.
    else {
      resultMarkup = (
        //Div with all the information retrieve from the pokemon API

        <div>
          <p>The base of the triangle is: {base}</p>
          <p>The height of the triangle is: {height}</p>
          <p>The area of the triangle is: {area}</p>
          <p>{error}</p>
        </div>
      );
    }
    return (
      //...
      <div>
        <form onSubmit={this.getArea}>
          <p>Calculate the base of a triangle!</p>
          <input
            type="text"
            id="base"
            placeholder="base"
            name="base"
            value={base}
            onChange={this.handleChange}
          />
          <input
            type="text"
            id="height"
            placeholder="height"
            value={height}
            name="height"
            onChange={this.handleChange}
          />
          <button type="submit">Get Area</button>

          {resultMarkup}
        </form>
      </div>
      //...
    );
  }
}

【讨论】:

  • 每当我在这种情况下使用状态时,都会出现错误。我得到的错误是。 ____ 属性 'area' 不存在于类型 'Readonly'.ts(2339) 上,这发生在底部和高度上。此错误来自在使用值时将 this.props 更改为 this.state。
  • @DanielIsaacChavez 是的,这是因为我们从未为您的组件状态定义接口。查看我更新的解决方案:)
  • 感谢您的帮助,您能否解释一下添加其他界面会产生怎样的重大变化。
  • @DanielIsaacChavez。是的!这是典型的 TypeScript 模式。如果您没有为您的组件状态定义接口,它将被保留为只读,因此我们将无法通过“this.setState()”对您的组件状态进行任何更改。您必须对几乎所有有状态的组件执行此操作。
  • @DanielIsaacChavez 如果您有任何其他问题,请告诉我。另外,如果您发现我的解决方案有助于解决您的问题,请将其标记为答案 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-27
  • 1970-01-01
  • 1970-01-01
  • 2011-12-12
  • 2014-03-14
  • 2015-04-29
  • 1970-01-01
相关资源
最近更新 更多