Властивість 'value' не існує для типу 'Readonly <{}>'


155

Мені потрібно створити форму, яка відображатиме щось на основі зворотного значення API. Я працюю з таким кодом:

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>
    );
  }
}

Я отримую таку помилку:

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

Я отримав цю помилку в двох рядках, коментував код. Цей код навіть не мій, я отримав його з офіційного сайту реагування ( https://reactjs.org/docs/forms.html ), але він тут не працює.

Я використовую інструмент створення-реагувати на додаток.


Ваша проблема полягає в іншому місці - дивіться цю демонстрацію
Тед

я знаю, його робота працює на всіх цих веб-сайтах "компілятора", але вони порадили мені використовувати це для проекту github.com/Microsoft/TypeScript-React-Starter , а через комплітер TypeScript це не працює
Луїс Анріке Циммерманн

Відповіді:


264

Component Визначається наступним чином:

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

Це означає , що тип за замовчуванням для держави (і реквізиту) є: {}.
Якщо ви хочете, щоб ваш компонент мав valueстан, тоді його потрібно визначити так:

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

Або:

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

3
omg, ty чувак, це працювало зараз, просто відповідь мені ще одне, цей синтаксис пов'язаний з TypeScript, так? тому що на офіційному сайті реагувати у нього немає нічого подібного
Luis Henrique Zimmermann

3
Так, це суворо стосується машинопису.
Нітзан Томер

1
Правильне визначення: клас Square розширює React.Component <{value: string}, {}> {...}
Rodrigo Perez Burgues

58

Окрім відповіді @ nitzan-tomer, у вас також є можливість використовувати інтерфейси :

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);
  ...
};

Або добре, поки ви послідовні.


1
Будь ласка, підведіть підсумки, які послідовні засоби знаходяться в контексті вашої публікації, щоб можна було мати її повну цінність без необхідності читати статтю із засобами масової інформації (що є чудовим корисним посиланням, дякую).
Карл Ріхтер

9

Проблема полягає в тому, що ви не оголосили стан інтерфейсу замінити будь-яким на відповідний змінний тип 'значення'

Ось хороша довідка

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

interface AppState {
   value: any
}

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

0

event.targetє типом, EventTargetякий не завжди має значення. Якщо це елемент DOM, вам потрібно надати його правильному типу:

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

Це дозволить зробити висновок про "правильний" тип для змінної стану, але, мабуть, явний варіант, ймовірно, краще


Я думаю, що він отримує помилку, коли намагається ініціалізувати рядок у конструкторі, а не обробник подій
Ray_Poly
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.