How to Pass Key value from inputText change in ReactJs in typescript?

I am using switch case for comparison for object key with string in below code:

import { TextField, Button } from "@material-ui/core";
import React, { Component, ReactNode } from "react";

import classes from "./Contact.module.scss";

class contactForm extends Component {
    state = {
        contactForm: {
            name: "",
            email: "",
            message: "",
            phone: ""
        }
    };

    render(): ReactNode {
        return (
            <form className={classes.ArticleBody}>
                <div className={classes.ContactForm}>
                    <TextField
                        value={this.state.contactForm.name}
                        onChange={event => this._inputChangeHandler(event, "name")}
                        label="Full Name"
                        required
                    />
                    <TextField
                        value={this.state.contactForm.email}
                        onChange={event => this._inputChangeHandler(event, "email")}
                        type="Email"
                        label="Email"
                        required
                    />
                    <TextField
                        value={this.state.contactForm.phone}
                        onChange={event => this._inputChangeHandler(event, "phone")}
                        type="phone"
                        label="Phone Number"
                        required
                    />
                    <TextField
                        type="textarea"
                        value={this.state.contactForm.message}
                        label="Comment/Message"
                        rows="4"
                        onChange={event => this._inputChangeHandler(event, "message")}
                        multiline
                        required
                    />
                </div>

                <div className={classes.Submit}>
                    <Button type="submit" onClick={this._submitContactForm}>
                        Submit
                    </Button>
                </div>
            </form>
        );
    }

    private _inputChangeHandler = (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>, key: string) => {
        const updatedFormData = { ...this.state.contactForm };
        switch (key) {
            case "email":
                updatedFormData.email = event.target.value;
                break;
            case "phone":
                updatedFormData.phone = event.target.value;
                break;
            case "message":
                updatedFormData.message = event.target.value;
                break;
            case "name":
                updatedFormData.name = event.target.value;
                break;
        }
        this.setState({ contactForm: updatedFormData });
    };

    private _submitContactForm = (event: React.MouseEvent<HTMLButtonElement, MouseEvent>): void => {
        event.preventDefault();
        console.log(this.state.contactForm);
    };
}

export default contactForm;

I don't want to compare my object keys with switch case. Is there any generic approach for changing values on input change for the defined state? e.g.: in below code I am trying to match key from parameter in method _inputChangeHandler but it throws error

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ name: string; email: string; message: string; phone: string; }'

const updatedFormData = { ...this.state.contactForm };
updatedFormData[key] = event.target.value;
this.setState({ contactForm: updatedFormData });

Thanks

try like this

this.setState({ contactForm: {...this.state.contactForm, [key]: event.target.value} });

@Ajay Verma

you could set the name attribute of the TextField and then you can get the key from the event.

like this

...
private _inputChangeHandler = (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
    const key = event.target.name;
...
<TextField
    value={this.state.contactForm.phone}
    name="phone"
    onChange={this._inputChangeHandler}
    type="phone"
    label="Phone Number"
    required
/>
...

Building a React Form Component with TypeScript: The Basics , Learn to use TypeScript's amazing type system with your existing JavaScript skills to interface IValues { /* Key value pairs for all the field values with key being the field name Form"; /* The available editors for the field */ type Editor = "textbox" TODO: push change to form values */ } onBlur={ (e: React. In this post, I will tell you, How to get input field value on button click in reactjs? Reactjs is a Javascript Library to build user interface. In this post, I made simple form and input field and input button. On button click, I am getting the input box value and this is tricky and in future post, I will do more this form.

The TextField has a name prop.

When you need to handle multiple controlled input elements, you can add a name attribute to each element and let the handler function choose what to do based on the value of event.target.name. React Docs

For example:

<TextField
  name="name"
  value={this.state.contactForm.name}
  onChange={this._inputChangeHandler}
  label="Full Name"
  required
/>

....

public _inputChangeHandler(e) {
  this.setState((prevState) => {
    return {
      contactForm: { 
        ...prevState.contactForm,     
        [e.target.name] : e.target.value
      }
    }
  });
}

ReactJS: Input fire onChange when user stopped typing (or pressed , I have encountered double triggerChange method call, when i changed value and immediately pressed enter_key . So, i would suggest to add clearTimeout into  Without further information, TypeScript can't know which value will be passed for the key parameter, so it can't infer a more specific return type for the prop function. We need to provide a little more type information to make that possible. The keyof Operator. Enter TypeScript 2.1 and the new keyof operator.

A general inputChangeHandler can be:

private _inputChangeHandler = (
  event: React.ChangeEvent<
    HTMLInputElement | HTMLTextAreaElement
  >,
  key: string
) => {
  this.setState({
    contactForm: {
      ...this.state.contactForm,
      [key]: event.target.value,
    },
  });
};

Your original code would work but you have to give typescript a hint when using bracket notation to access a property:

const contactForm: {
  [key: string]: string;
} = {
  ...this.state.contactForm,
};
contactForm[key] = event.target.value;

this.setState({
  contactForm,
});

How to "onchange" in ReactJS, Normally, in vanilla Javascript, the onchange event is triggered after you If you execute that kind of validation on every key stroke, it's unlikely to be a pleasant UI​. the React app's state, not from the browser's idea of what the value should be. https://daveceddia.com/avoid-bind-when-passing-props/ ---. Example: Pass an Input Value from the onChange Event in a React Component. Let’s expand on the previous example by declaring a new function inside of our React component for the onChange handler to pass a value to. We’ll call it handleChange, and have it log the input’s current value to the console:

Handling Multiple Inputs with a Single onChange Handler in React , With a text input field like this, we can pass the onChange prop: To do this, we'll add some React state and set the input field's value prop with it: Because the form name props match the state property keys, the firstName  Since handleChange runs on every keystroke to update the React state, the displayed value will update as the user types. With a controlled component, the input’s value is always driven by the React state. While this means you have to type a bit more code, you can now pass the value to other UI elements too, or reset it from other event handlers.

How works event.target.value? - JavaScript, setState({event.target.value}) } // change code above this line render() { return https://learn.freecodecamp.org/front-end-libraries/react/create-a-controlled-input the value from the input textbox but it is not updating the input key in your state Inside the constructor, initialize the state with an empty string value for text. changeText method takes one string as input and changes the value of text in the state using setState method. It adds one Unicode character to the start of the string before setting the state. It takes one string as a parameter.

Forms – React, An input form element whose value is controlled by React in this way is called a <label> Name: <input type="text" value={this.state.value} onChange={this. have to type a bit more code, you can now pass the value to other UI elements too, name syntax to update the state key corresponding to the given input name:. A protip by fr0gs about react and typescript. The problem with Typescript's React typings is that the SyntheticEvent that is generated does not know that the originating DOM node is an input node.

Comments
  • Thank you for your answer, I don't want to open another question but Can I use something generic for harcoded key value in onChange method: onChange={event => this._inputChangeHandler(event, "name")} here "name" is hardcoded.
  • okay.. thank you.. that'll remove my extra parameter from method. Thank you for the links
  • Thank you for your response too. It is same as marked answer and both works perfectly. :)
  • @AjayVerma It probably is type inference problem, if you define a type for conatactForm your code would probably work as well.
  • Okay.. I didn't know that thank you for suggestion I'll definitely try to do that also, I don't want to open another question but Can I use something generic for harcoded key value in onChange method: onChange={event => this._inputChangeHandler(event, "name")} here "name" is hardcoded.
  • @AjayVerma Updated my answer, your code would have worked if you give typescript a hint to be ok with bracket notation (object[key])
  • Thank you. I'll give it a try and will also look into the interface problem that you mentioned earlier. Thank you for your help. I am learning React, so sorry if I seem confused.