Search code examples
javascriptreact-state-managementreact-statereactjs

State not being updated in React.js


I have created a basic form in react.js where I am able to get the values after the user submits the form.

However, when I try to change the values using the handleSubmit function, I don't see the changes made in the state.

I have made a copy of a state and changes are being reflected in the Copied State. But when I set the old state equal to the updated state, the changes are not reflected

My code is as follows

    state = {    
        name: null,
        ContactNumber: null

    }

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

    handleSubmit = (event) => {
        event.preventDefault()
        let Copystate = JSON.parse(JSON.stringify(this.state))
        Copystate.ContactNumber = 100

        console.log(Copystate) // displaying the contact number as 100

        this.setState({
            state : Copystate
        })

        console.log(this.state) // displays the number which was submitted in the form

    }
    render(){
        return(
            <div>
                <h2>Form</h2>
                <form onSubmit={this.handleSubmit}>
                    <div>
                        <label>Name</label>
                        <input type="text" name="name" required = {true} onChange = {this.handleChange}/>

                        <label>Contact Number</label>
                        <input type="number" name="ContactNumber" required = {true} onChange = {this.handleChange}/>

                        <button type="submit" label="submit" >Submit</button>
                    </div>
                </form>
            </div>
        );
    }
}

Can anyone please let me know where I am going wrong? Thanks


Solution

  • Notice: setState is asynchronous: document state-updates-may-be-asynchronous

    You can use a callback function to get the updated state

    this.setState({state: Copystate}, () => {console.log(this.state)});
    

    Or you can choose to use async/await

    handleSubmit = async (event) => {
      await this.setState({state: Copystate});
      console.log(this.state);
    }
    

    Those two methods won't affect re-render since once the state is been updated, the re-render would proceed.

    If you console in the render() you would find that it should always be updated finally.

    render() {
      console.log(this.state);
      return (
        ...
      )
    }