Socrates
Socrates

Reputation: 9574

React setState dynamically using string

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

Answers (1)

Rohit Mishra
Rohit Mishra

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

Related Questions