Search code examples
javascriptreactjssetstatereact-component

setState not working for objects inside the this.state in ReactJs


I am working with forms in React and facing this weird issue.

This is how my component class looks -

export default class Home extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
        username: 'Bla'
    };

    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(event) {
    this.setState({[event.target.name]: event.target.value})
  }

  render() {
      return (
         <div>
            <form onChange={this.handleChange}>
              <label> Name: <input type="text" value={this.state.username} name="username" /> </label>
              <input type="submit" value="Submit" />
            </form>
         </div>
      );
   }
}

And this is how the rendered page looks in the browser.

enter image description here

I am able to update/change the text in the textbox.

Now I tweak my component class a bit, basically I change the this.state object and correspondingly update the HTML input element.

These are the changes done-

this.state = {
   formEle: {
      username: 'Bla'
   }
};

<label> Name: <input type="text" value={this.state.formEle.username} name="username" /> </label>

After making these two changes when I render the page in my browser everything is same except I am not able to update/change the content in the textbox.

My hunch is there must be some issue with the this.setState function, but when I printing the values of event.target.name and event.target.value I am getting the expected value. Not sure what exactly is going wrong.


Solution

  • The reason you're no longer able to update your input box is that you're no longer setting the correct state variable.

    If you change your handleChange event listener to look like this, stuff should start working again:

    handleChange(event) {
      this.setState({ 
        formEle: {
          ...this.state.formEle,
          [event.target.name]: event.target.value,
        },
      });
    }
    

    You specified that you want to read state from this.state.formEle.username, so therefore you need to make sure you're setting that particular part of the state tree.

    Hope this helps - and happy coding!