简体   繁体   中英

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>

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"}>

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM