I have som react state that was defined as an interface and has specificall named keys...
I tried a solution below that should technically work based on the state keys, but it still gives me the error
{ [x: string]: string; }' provides no match for the signature ...
What is the best way to do this...
interface State {
responses: string,
comments: string,
}
state = {
responses: '',
comments: '',
};
handleChange = (e: React.ChangeEvent<HTMLInputElement>, value: string): void => {
const key = e.currentTarget.name;
Object.keys(this.state).forEach(k => {
if (k === key) this.setState({ [e.currentTarget.name]: value });
})
}
public onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
this.setState({
[e.currentTarget.name]: e.currentTarget.value
} as { [K in keyof IState]: IState[K] });
};
IState
- interface of this.state
The return type of Object.keys()
is the generic string[]
rather than an array of the union of the keys of the object, so it's probably tricky to infer the correct types here. Moreover, in my experience, smart solutions have a tendency to break when newer versions of TypeScript or package type definitions are released, so in this case I would just help TypeScript with a signature on to the argument of setState
:
handleChange = (e: React.ChangeEvent<HTMLInputElement>, value: string): void => {
const key = e.currentTarget.name;
if (Object.keys(this.state).includes(key)) {
this.setState({[key]: value } as Pick<State, keyof State>);
}
}
One option would be instead of iterating through keys, to use switch statement. Although it will produce more code:
switch (key) {
case 'responses':
this.setState({ responses: value });
break;
case 'comments':
this.setState({ comments: value });
break;
}
If you declare state with type number then use this code for update state:
this.setState({ ...this.state, [event.currentTarget.name]: Number(event.target.value) });
If you declare state with type string then use this code for update state:
this.setState({ ...this.state, [event.currentTarget.name]: event.target.value });
Full code:
onChange =(event: React.ChangeEvent<HTMLInputElement>) => {
this.setState({ ...this.state, [event.currentTarget.name]: Number(event.target.value) });
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With