Thuộc tính 'giá trị' không tồn tại trên loại 'Chỉ đọc <{}>'


154

Tôi cần tạo một biểu mẫu sẽ hiển thị một cái gì đó dựa trên giá trị trả về của API. Tôi đang làm việc với đoạn mã sau:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value); //error here
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} /> // error here
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

Tôi nhận được lỗi sau:

error TS2339: Property 'value' does not exist on type 'Readonly<{}>'.

Tôi đã nhận được lỗi này trong hai dòng tôi nhận xét về mã. Mã này thậm chí không phải của tôi, tôi đã nhận được nó từ trang web chính thức phản ứng ( https://reactjs.org/docs/forms.html ), nhưng nó không hoạt động ở đây.

Tôi đang sử dụng công cụ tạo ứng dụng.


Vấn đề của bạn nằm ở nơi khác - xem Bản demo này
Ted

Tôi biết, nó hoạt động trên tất cả các trang web "trình biên dịch" này, nhưng họ khuyên tôi nên sử dụng nó để thực hiện dự án github.com/Microsoft/TypeScript-React-Starter và thông qua trình soạn thảo TypeScript, nó không hoạt động
Luis Henrique Zimmermann

Câu trả lời:


263

Các Component được định nghĩa như sau:

interface Component<P = {}, S = {}> extends ComponentLifecycle<P, S> { }

Có nghĩa là loại mặc định cho trạng thái (và đạo cụ) là : {}.
Nếu bạn muốn thành phần của mình có valuetrạng thái thì bạn cần xác định nó như thế này:

class App extends React.Component<{}, { value: string }> {
    ...
}

Hoặc là:

type MyProps = { ... };
type MyState = { value: string };
class App extends React.Component<MyProps, MyState> {
    ...
}

3
omg, ty dude, nó đã hoạt động rồi, chỉ cần trả lời tôi một điều nữa, cú pháp này có liên quan đến TypeScript phải không? bởi vì trong trang web chính thức phản ứng, nó không có gì tương tự
Luis Henrique Zimmermann

3
Vâng, đây là nghiêm ngặt bản thảo liên quan.
Nitzan Tomer

1
Định nghĩa đúng là: class Square mở rộng React.Component <{value: string}, {}> {...}
Burgrigo Perez Burgues

58

Ngoài câu trả lời @ Nitzan-Tomer, bạn cũng có tùy chọn để sử dụng inferfaces :

interface MyProps {
  ...
}

interface MyState {
  value: string
}

class App extends React.Component<MyProps, MyState> {
  ...
}

// Or with hooks, something like

const App = ({}: MyProps) => {
  const [value, setValue] = useState<string>(null);
  ...
};

Hoặc là tốt, miễn là bạn nhất quán.


1
Vui lòng tổng hợp ý nghĩa nhất quán trong ngữ cảnh của bài đăng của bạn để có thể có đầy đủ giá trị của nó mà không cần phải đọc bài viết trung bình (đây là một liên kết hữu ích tuyệt vời, cảm ơn bạn).
Karl Richter

8

Vấn đề là bạn chưa khai báo trạng thái giao diện của bạn thay thế bất kỳ bằng loại biến 'giá trị' phù hợp của bạn

Đây là một tài liệu tham khảo tốt

interface AppProps {
   //code related to your props goes here
}

interface AppState {
   value: any
}

class App extends React.Component<AppProps, AppState> {
  // ...
}

0

event.targetthuộc loại EventTargetkhông phải lúc nào cũng có giá trị. Nếu đó là một phần tử DOM, bạn cần chuyển nó thành đúng loại:

handleChange(event) {
    this.setState({value: (event.target as HTMLInputElement).value});
}

Điều này cũng sẽ suy ra kiểu "chính xác" cho biến trạng thái mặc dù rõ ràng có lẽ tốt hơn


Tôi nghĩ rằng anh ta đã gặp lỗi khi cố gắng khởi tạo chuỗi trong hàm tạo, chứ không phải trình xử lý sự kiện
Ray_Poly
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.