maraxai
maraxai

Reputation: 145

How to prevent state change in React after page refresh/view change?

My onClick-event handler adds/removes an id to a database field and changes the button color according to the toggle state true/false. While the data update works correctly, the color state resets upon a page refresh/view change. I guess the state needs to be passed on (the relationship is child to parent in this case) with a callback function but I am not sure.

I thought it would be necessary to 'preserve' the current state in LocalStorage but this did not solve the issue. While the LocalStorage values 'true' and 'false' remained their state (as displayed in the console), the color of the button still reset when refreshing the page.

I attached the code sections that may be of importance to assess the issue:

// initialization of toggle state
let toggleClick = false;

...

 this.state = {
      fav: props.favorite
    };
    this.toggleClass = this.toggleClass.bind(this);
  }

...

componentDidUpdate(prevProps) {
    if (this.props.favorite !== prevProps.favorite) {
      this.setState({
        fav: this.props.favorite
      });
    }
  }

  toggleClass() {
    toggleClick = true;
    if (!this.state.fav) {
      this.addId(this.props.movie._id);
    } else {
      this.removeId();
    }
  }

...

<span
  onClick={() => this.toggleClass()}
  className={this.state.fav ? "favme active" : "favme"}
>&#x2605;</span>

Upvotes: 2

Views: 26239

Answers (2)

Deepak Kumrawat
Deepak Kumrawat

Reputation: 744

I had a similar issue when refreshing the view. It was because the component render before the rehydration was complete. I solved my problem by using Redux Persist. We can delay the render by using Redux Persist, I put the persistStore in my main component:

componentWillMount() {
  persistStore(store, {}, () => {
  this.setState({rehydrated: true})
  })
}

This will ensure that the component re-render when the store is rehydrated.

https://github.com/rt2zz/redux-persist

Upvotes: 0

josemartindev
josemartindev

Reputation: 1426

I have encountered your same problem for my React Apps. For this, I always use componentDidMount because it is called just after the render. But, if you call the setState function, it will automatically call the render, so your changes will appear. If page gets refreshed, state will be reset to default. So, the best way to achieve this is for example:

componentDidMount() {
   const getDbAnswer = //fetch a signal from the db
   if (getDBAnswer === true) {
     this.setState({ fav: true })
   else
     this.setState({ fav: false })
}

You could even set a variable with localStorage. Remember, localStorage accepts only string values, no boolean.

componentDidMount() {
  const getDbAnswer = //fetch a signal from the db
  if (getDBAnswer === true)
    localStorage.setItem("fav", "true");
  else
    localStorage.setItem("fav", "false");
}

And then you could just use it like this:

<div className={localStorage.getItem("fav") === "true" ? "favme active" : "favme"}>

Upvotes: 0

Related Questions