ChatGPT解决这个技术问题 Extra ChatGPT

Property 'value' does not exist on type 'Readonly<{}>'

I need to create a form that will display something based on the return value of an API. I'm working with the following code:

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

I'm getting the following error:

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

I got this error in the two lines I commented on the code. This code isn't even mine, I got it from the react official site (https://reactjs.org/docs/forms.html), but it isn't working here.

Im using the create-react-app tool.

Your problem lies elsewhere--see This demo
i know, its working on all these "compiler" websites, but they advised me to use this to do the project github.com/Microsoft/TypeScript-React-Starter, and through the TypeScript compliter, it is not working

N
Nitzan Tomer

The Component is defined like so:

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

Meaning that the default type for the state (and props) is: {}.
If you want your component to have value in the state then you need to define it like this:

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

Or:

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

omg, ty dude, it worked now, just answer me one more thing, this syntax is related to TypeScript right? because in react official site it doesnt have anything similar
Yes, this is strictly typescript related.
The right define is: class Square extends React.Component<{ value: string }, { }> { ... }
@NitzanTomer - You saved my day
L
Leo
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>('');
  ...
};

type's are fine too like in @nitzan-tomer's answer, as long as you're consistent.


Please sum up what consistent means in the context of your post so that it's possible to have its full value without the need to read the medium article (which is a great useful link, thank you).
S
Siphenathi

If you don't want to pass interface state or props model you can try this

class App extends React.Component <any, any>

A
Aravin

I suggest to use

for string only state values

export default class Home extends React.Component<{}, { [key: string]: string }> { }

for string key and any type of state values

export default class Home extends React.Component<{}, { [key: string]: any}> { }

for any key / any values

export default class Home extends React.Component<{}, { [key: any]: any}> {}

M
Minuka ArTy Weerathunga

The problem is you haven't declared your interface state replace any with your suitable variable type of the 'value'

Here is a good reference

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

interface AppState {
   value: any
}

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

M
Mselmi Ali

According to the official ReactJs documentation, you need to pass argument in the default format witch is:

P = {} // default for your props
S = {} // default for yout state

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

Or to define your own type like below: (just an exp)

interface IProps {
    clients: Readonly<IClientModel[]>;

    onSubmit: (data: IClientModel) => void;
}

interface IState {
   clients: Readonly<IClientModel[]>;
   loading: boolean;
}

class ClientsPage extends React.Component<IProps, IState> {
  // ...
}

typescript and react whats react component P S mean

how to statically type react components with typescript


a
apokryfos

event.target is of type EventTarget which doesn't always have a value. If it's a DOM element you need to cast it to the correct type:

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

This will infer the "correct" type for the state variable as well though being explicit is probably better


I think he gets the error when tries to initialize the string in the constructor, not the event handler
B
Bogdan P.

My solution

    import React, { ChangeEvent, FormEvent } from "react";
    
    interface NameFormProps {
    }
    
    interface NameFormState {
      value: string
    }
    
    export default class NameForm extends React.Component<NameFormProps, NameFormState> {
      constructor(props: any) {
        super(props);
        this.state = {value: ''};
    
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
      }
    
      handleChange(event: ChangeEvent<HTMLInputElement>) {
        this.setState({value: event.target.value});
    }
    
      handleSubmit(event: FormEvent<HTMLFormElement>) {
        alert('A name was submitted: ' + this.state.value);
        event.preventDefault();
      }
    
      render() {
        return (
          <form onSubmit={this.handleSubmit}>
            <label>
              Name:
              <input type="text" value={this.state.value} onChange={this.handleChange} />
            </label>
            <input type="submit" value="Submit" />
          </form>
        );
      }
    }

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.