Search code examples
reactjseventslocal-storageonchangesetstate

setState logs older value when attempted saving it to LocalStorage


Even there's a work around to solve this, I want to learn why current approach of mine below isn't successful. I wonder why local storage logs the previous value of the state even it's bonded with setState?

Explanation:

There's an input field with it's onChange function to check whenever user types and saves it to localStorage correctly.

<input required type="text" className="form-control" id="hotelName" name="hotelName" onChange={this.onInputChange} />

onInputChange(event) {
    localStorage.setItem('hotelCreateStep1', JSON.stringify(event.target.value));
}

Situation:

Hence, when it's intended to write the event.target.value to the state object before writing it to localStorage as explained below, it writes the previous value of the object (missing only the lastly typed letter or input attempt of any kind).

onInputChange(event) {
    this.setState({
        hotelCreateStep1:{
            ...this.state.hotelCreateStep1,
            [event.target.name]: event.target.value
        }
    });
    localStorage.setItem('hotelCreateStep1', JSON.stringify(this.state.hotelCreateStep1));
}

Solution

  • setState in react is asynchronous. So whenever you call setState then the value will not get reflected then itself. For more info about setState and the callback which it takes refer here.

    So the issue can be resolved in two ways

    • Use setState callback to update the localStorage like below
    onInputChange(event) {
        this.setState({
            hotelCreateStep1:{
                ...this.state.hotelCreateStep1,
                [event.target.name]: event.target.value
            }
        }, () => {
        localStorage.setItem('hotelCreateStep1', JSON.stringify(this.state.hotelCreateStep1))
      });;
    }
    
    • Or use event.target.value value directly in the localStorage
    onInputChange(event) {
        this.setState({
            hotelCreateStep1:{
                ...this.state.hotelCreateStep1,
                [event.target.name]: event.target.value
            }
        });
        localStorage.setItem('hotelCreateStep1', event.target.value);
    }