Set react state dynamically in typescript

09/10/2020 21:15
Set react state dynamically in typescript
 
1. define interface for state and state keys
2. use dynSetState method in handleChange handler
 
export interface IMasterFormState {
    currentStep: number;
    email?: string | null | undefined;
    userName: string;//string | null | undefined;
    nick?: string | null | undefined;
    hasLongHair: boolean;
}
 
type StateKeys = keyof IMasterFormState;
 
export default class MasterForm extends React.Component<IMasterFormProps, IMasterFormState> {
    constructor(props: IMasterFormProps, state: IMasterFormState) {
        super(props);
        this.state = { currentStep: 1, email: "", userName: "", nick: "", hasLongHair: false };
 
        // Bind the submission to handleChange() 
        this.handleChange = this.handleChange.bind(this)
    
    }
 
    public render(): React.ReactElement {
        console.log(this.state);
        return (
            <React.Fragment>
<div className="form-group">
                <label htmlFor="userName">User name</label>
                <input
                    className="form-control"
                    id="userName"
                    name="userName"
                    type="text"
                    placeholder="Enter username"
                    value={this.props.userName} 
                    onChange={this.props.handleChange}
                />
             </div>
<div className="form-group">
<label htmlFor="email">Email address</label>
<input
className="form-control"
id="email"
name="email"
type="text"
placeholder="Enter email"
value={this.props.email} 
onChange={this.props.handleChange}
/>
</div>
</React.Fragment>
        )
    }
 
handleChange(event: any) {
        const {name, value} = event.target
        this.dynSetState(name, value);
        console.log(`name: ${name}`);
        console.log(`value: ${value}`);
      }
 
    dynSetState<K extends StateKeys>(key: K, value: IMasterFormState[K]) {
        this.setState({ [key]: value } as Pick<IMasterFormState, K>); // clean cast works
      }
}
when js syntax for setState is not working in typescript
 
handleChange(event) {
    const {name, value} = event.target
    this.setState({
      [name]: value
    })    
  }
 
 
1. define interface for state and state keys
2. use dynSetState method in handleChange handler
 
export interface IMasterFormState {
    currentStep: number;
    email?: string | null | undefined;
    userName: string;//string | null | undefined;
    nick?: string | null | undefined;
    hasLongHair: boolean;
}
 
type StateKeys = keyof IMasterFormState;
 
export default class MasterForm extends React.Component<IMasterFormProps, IMasterFormState> {
    constructor(props: IMasterFormProps, state: IMasterFormState) {
        super(props);
        this.state = { currentStep: 1, email: "", userName: "", nick: "", hasLongHair: false };
 
        // Bind the submission to handleChange() 
        this.handleChange = this.handleChange.bind(this)
    
    }
 
    public render(): React.ReactElement {
        console.log(this.state);
        return (
            <React.Fragment>
<div className="form-group">
                <label htmlFor="userName">User name</label>
                <input
                    className="form-control"
                    id="userName"
                    name="userName"
                    type="text"
                    placeholder="Enter username"
                    value={this.props.userName} 
                    onChange={this.props.handleChange}
                />
             </div>
<div className="form-group">
<label htmlFor="email">Email address</label>
<input
className="form-control"
id="email"
name="email"
type="text"
placeholder="Enter email"
value={this.props.email} 
onChange={this.props.handleChange}
/>
</div>
</React.Fragment>
        )
    }
 
handleChange(event: any) {
                const {name, value} = event.target
                this.dynSetState(name, value);
                console.log(`name: ${name}`);
                console.log(`value: ${value}`);
      }
 
    dynSetState<K extends StateKeys>(key: K, value: IMasterFormState[K]) {
        this.setState({ [key]: value } as Pick<IMasterFormState, K>); // clean cast works
      }
}