Reputation: 9574
How can I set and existing state field dynamically in a React component?
My current tries lead to the following approach, but it does not work in TypeScript:
export interface MaskCompanyDetailState {
fieldId: number;
}
export class MaskCompanyDetail extends React.Component<MaskCompanyDetailProps, MaskCompanyDetailState> {
public constructor(props: any) {
super(props);
// Set field defaults.
this.state = {
fieldId: 0,
};
}
public componentDidMount() {
const myField: string = 'fieldId';
const myVal: number = 123;
this.setState({[myField]: myVal});
this.setState({myField: myVal});
}
}
Error message from TSLint for this.setState({[myField]: myVal});
:
Argument of type '{ [x: string]: number; }' is not assignable to parameter of type 'MaskCompanyDetailState | ((prevState: Readonly, props: Readonly) => MaskCompanyDetailState | Pick<...>) | Pick<...>'. Type '{ [x: string]: number; }' is missing the following properties from type 'Pick': fieldId, fieldCompanyName, fieldStreetName, fieldStreetNumber, and 4 more.ts(2345)
Error message from TSLint for this.setState({myField: myVal});
:
Argument of type '{ myField: number; }' is not assignable to parameter of type 'MaskCompanyDetailState | ((prevState: Readonly, props: Readonly) => MaskCompanyDetailState | Pick<...>) | Pick<...>'. Object literal may only specify known properties, and 'myField' does not exist in type 'MaskCompanyDetailState | ((prevState: Readonly, props: Readonly) => MaskCompanyDetailState | Pick<...>) | Pick<...>'.ts(2345)
There is already a post here, but I don't see how to apply the suggested IState
interface.
Upvotes: 1
Views: 2336
Reputation: 151
Add the following field to MaskCompanyDetailState
interface -
[key: string]: any;
i.e.,
interface MaskCompanyDetailState {
... // existing fields
[key: string]: any;
}
It means that you are allowing any property which has a key of type string
and value of any
type to be set in your state.
This is what your linked post says. This is an example of Index Signature
which is a feature of Typescript.
It's not really recommended, because it affects readability of your code in the long run and other people in your team may abuse it. But I am not aware of any other solutions to your predicament other than to rethink your design.
Upvotes: 3