You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS + TypeScript组件报错求助:Property 'height'不存在于Readonly<{}>

解决React TypeScript类组件中Property 'height' does not exist on type 'Readonly<{}>'错误

这个报错的核心原因是TypeScript无法推断出你的组件state的结构,默认把state类型当成了空对象Readonly<{}>,所以当你访问this.state.base或this.state.height时,TS会认为这些属性不存在。下面是一步步的修复方案:

1. 定义State的类型接口

首先我们需要明确state的结构,创建一个接口来描述它:

interface TriangleState {
  base: number | undefined;
  height: number | undefined;
  area: number | undefined;
  error: string;
}

然后在组件类中指定state的类型(同时把组件名改成首字母大写,符合React组件命名规范):

export default class TriangleArea extends React.Component<triangleInfo, TriangleState> {
  // ...
}

2. 修复handleChange方法的逻辑

你的handleChange方法里错误地使用了name作为state的键,但你的input元素没有设置name属性,也没有区分是base还是height的输入。我们可以给input添加name属性(和state的字段名一致),然后动态更新对应的state:

handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
  // 将输入的字符串转为数字,空值则设为undefined
  const value = event.target.value ? Number(event.target.value) : undefined;
  this.setState({
    [event.target.name]: value
  } as Pick<TriangleState, 'base' | 'height'>);
}

同时修改input元素,添加name属性并把类型改成number(限制用户输入非数字内容):

<input 
  type="number" 
  id="base" 
  name="base"
  placeholder="base" 
  value={this.state.base ?? ''} 
  onChange={this.handleChange}
/>
<input 
  type="number" 
  id="height" 
  name="height"
  placeholder="height" 
  value={this.state.height ?? ''} 
  onChange={this.handleChange}
/>

这里用?? ''处理undefined的情况,避免input出现"undefined"字符串。

3. 修复getArea方法的问题

  • 给方法的参数指定类型:React.FormEvent<HTMLFormElement>
  • 处理字符串转数字的问题(虽然input是number类型,但value依然是string,需要转成number)
  • 给form添加onSubmit绑定,触发getArea方法

修正后的getArea:

getArea = (event: React.FormEvent<HTMLFormElement>) => {
  event.preventDefault();
  const base = Number(event.currentTarget.elements.base.value);
  const height = Number(event.currentTarget.elements.height.value);

  if (!isNaN(base) && base > 0 && !isNaN(height) && height > 0) {
    this.setState({
      base,
      height,
      area: (base * height) / 2,
      error: ""
    });
  } else {
    this.setState({
      base: undefined,
      height: undefined,
      area: undefined,
      error: "Please enter positive numbers for base and height."
    });
  }
}

然后修改form标签,添加onSubmit:

<form onSubmit={this.getArea}>

完整修正后的代码

import React from 'react';

// 假设你的props类型是这样的,如果没有实际props可以改成{}
interface triangleInfo {}

interface TriangleState {
  base: number | undefined;
  height: number | undefined;
  area: number | undefined;
  error: string;
}

export default class TriangleArea extends React.Component<triangleInfo, TriangleState> { 
  constructor(props: triangleInfo) { 
    super(props); 
    this.state = { 
      base: undefined, 
      height: undefined, 
      area: undefined, 
      error: "" 
    }; 
  } 

  handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const value = event.target.value ? Number(event.target.value) : undefined;
    this.setState({
      [event.target.name]: value
    } as Pick<TriangleState, 'base' | 'height'>);
  }

  getArea = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    const base = Number(event.currentTarget.elements.base.value);
    const height = Number(event.currentTarget.elements.height.value);

    if (!isNaN(base) && base > 0 && !isNaN(height) && height > 0) {
      this.setState({
        base,
        height,
        area: (base * height) / 2,
        error: ""
      });
    } else {
      this.setState({
        base: undefined,
        height: undefined,
        area: undefined,
        error: "Please enter positive numbers for base and height."
      });
    }
  }

  render() { 
    return ( 
      <div> 
        <form onSubmit={this.getArea}> 
          <p>Calculate the area of a triangle!</p>
          <input 
            type="number" 
            id="base" 
            name="base"
            placeholder="base" 
            value={this.state.base ?? ''} 
            onChange={this.handleChange}
          /> 
          <input 
            type="number" 
            id="height" 
            name="height"
            placeholder="height" 
            value={this.state.height ?? ''} 
            onChange={this.handleChange}
          /> 
          <button type="submit">Get Area</button> 
        </form>
        {this.state.area && <p>Triangle Area: {this.state.area}</p>}
        {this.state.error && <p style={{color: 'red'}}>{this.state.error}</p>}
      </div> 
    ); 
  } 
};

额外说明

  • 组件名首字母大写是React的规范,避免和HTML标签冲突
  • 使用event.currentTarget而不是target,在表单提交时更可靠
  • 添加了面积展示和错误提示的UI,提升用户体验
  • 用isNaN判断转换后的数字是否有效,避免非数字输入导致的计算错误

内容的提问来源于stack exchange,提问作者Daniel Isaac Chavez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:26:13