Search code examples
javascriptreactjstypescriptreact-tsx

Updating from an input element in ReactJS


I'm attempting to create a page using React, whereby I can update a single element of the state; here is how the state is defined:

interface MyState {
    data?: MyData;
    loading: boolean;
}

interface MyData {
    id: number;
    description: string;
    test: string;    
}

I have the following inside my render function:

return <div>
    <h1>Description: {myData.description}</h1>
    <br/><br/>
    <input type="text" value={emailType!.test} onChange={this.handleChange} />

</div>;

And the handleChange (which is the heart of my issue):

handleChange(event: React.FormEvent<HTMLInputElement>) {        
    this.setState({ emailType!.test: event.currentTarget.value });
}

As I'm using tsx, the function above won't even compile. However, it does illustrate what I'm trying to do. Typically, when I've called this.setState, I've done so with a full state (that is, I know the entire new state). In this case, I only want to change the contents of a single field: is that possible?


Solution

  • setState allows changing only top-level key in the state like

    handleChange = (event: React.FormEvent<HTMLInputElement>) => {
        const emailType = { ...emailType, test: event.currentTarget.value }
        this.setState({ emailType })
    }
    

    Don't forget to bind your function to the proper context.

    Another option is to use function as a parameter in setState:

    this.setState((oldState) => {
      return {
        ...oldState,
        emailType: {
          ...oldState.emailType,
          test: event.currentTarget.value
        }
      }
    })