Jonas Kgomo
Jonas Kgomo

Reputation: 163

ReactJS: How can I update state of property using localStorage?

I have a component with the following initial state:

  constructor(props) {
    super(props)
    this.state = {
      currentId: 0,
      pause: true,
      count: 0,
      storiesDone: 0
    }
    this.defaultInterval = 4000
    this.width = props.width || 360
    this.height = props.height || 640
  }

I have to start from currentId = 0 and then update the state of the component, even after a page refresh.

I want to restore currentId = 1 after persisting a value of 1.

I am getting an error that the property cannot change , when I try replacing currentId = localStorage.getItem('currentId') in the above code.

    var currentId = this.state.currentId;    
      localStorage.setItem( 'currentId', 1);
      console.log(currentId);
      localStorage.getItem('currentId');

I also tried:

  _this.setState((state) => {
      return {currentId: localStorage.getItem('currentId')};
    });

Upvotes: 3

Views: 1329

Answers (2)

Ken Labso
Ken Labso

Reputation: 911

Use componentDidMount. See the code below. I added checking if localStorage.currentId have value. If it have, check if the value from localStorage.currentId match state's currentId and if it don't then update the state to the value from localStorage.

state = {
  currentId: 0,
  pause: true,
  count: 0,
  storiesDone: 0
}
componentDidMount() {
  //Assign localStorage.get("currentId") to a variable
  const localCurrentId = localStorage.get("currentId");
  //Check if localCurrentId is not null or undefined
  if (localCurrentId) {
    this.setState(prevState => ({
      //Update state's currentId if the current value didn't match with localCurrentId
      currentId: prevState.currentId !== localCurrentId ? localCurrentId : prevState.currentId
    }));
  }
}

Upvotes: 1

Dacre Denny
Dacre Denny

Reputation: 30390

The value type persisted to localStorage must be a string.

Consider revising the code that interacts with localStorage so that the state value currentId is first converted to a string before it is passed to localStorage.setItem().

Also note that string values are returned by localStorage.getItem() when a key is present, which means you should parse the returned value to obtain currentId as a number.

Something along the lines of this should work:

const saveCurrentId = () => {    

    const { currentId } = this.state;    

    /* Format string from value of currentId and persist */
    localStorage.setItem( 'currentId', `${ currentId }`);
}

const loadCurrentId = (fallbackValue) => {

    /* Load currentId value from localStorage and parse to integer */
    const currentId = Number.parseInt(localStorage.getItem('currentId'));

    /* Return currentId if valid, otherwise return fallback value */
    return Number.isNaN(currentId) ? fallbackValue : currentId;
}

With the code above, you can then update your components constructor to automatically load and apply the persisted currentId as follows:

 constructor(props) {
    super(props)
    this.state = {

      /* Use 0 as fallback if no persisted value present */
      currentId: this.loadCurrentId( 0 ), 

      pause: true,
      count: 0,
      storiesDone: 0
    }
    this.defaultInterval = 4000
    this.width = props.width || 360
    this.height = props.height || 640
  }

Upvotes: 2

Related Questions