1

I'm looking for a solution - react router v4 doesn't hold the previous state of component. For example, here is a simple counter:

import React, { Component } from "react";

class Schedule extends Component {
  constructor(props) {
    super(props);
    this.state = {
      counter: 0
    };
    this.holdState = this.holdState.bind(this);
  }

  holdState() {
    this.props.location.state = this.state.counter;
    const state = this.state;
    this.setState({
      counter: state.counter + 1
    });
  }

  render() {
    return (
      <div>
        <ul>
          <li>6/5 @ Evergreens</li>
          <li>6/8 vs Kickers</li>
          <li>6/14 @ United</li>
        </ul>
        <div>
          <button onClick={() => this.holdState()}>Click</button>
          <span>{this.state.counter}</span>
        </div>
      </div>
    );
  }
}

export default Schedule;

I was trying to push the state into location and history by props. But whenever I press "browser button back" from the next page, it always resets the state. Can someone tell me where I'm doing a mistake?

Martin Reiche
  • 1,642
  • 1
  • 16
  • 27
wawrzon
  • 13
  • 4
  • Not sure what you are trying to achieve. Do you want to store the counted value based on the url? So e.g. in the query params? – Martin Reiche May 02 '18 at 09:05

2 Answers2

0

I was trying to push state into location and history by props. BBut whenever I > press "browser button back" from the next page, it always resets the state.

when you call setState you're not changing the route, you're just triggering a rerender of your component. If you press the back button after incremented the counter react router will symply pop the last route from the history stack but since you don't have a previous route the component will be remount hence the resetted state.

To implement what i suppose you want to achieve you need to explicitely change the route every setstate (e.g. adding a parameter in the query string with the current value of the counter, like ?counter=1, ?counter=2..) , this way you'll be sure that a new route will be push on top of the stack every setState and the back button will then work as you expect.

Karim
  • 8,454
  • 3
  • 25
  • 33
0

Whenever your component mounts, your constructor will be initiated which will reset the state back to 0. This happens when you are on another component and press back button in which case your current Route gets mounted.

Also directly mutating the location.state value is not a right approach. What you need is to save your value in localStorage and refill it in state if it exists.

Another thing is that when you wish to update the state based on prevState, you could make use of functional setState. Check this for more details: When to use functional setState

import React, { Component } from "react";

class Schedule extends Component {
  constructor(props) {
    super(props);
    this.state = {
      counter: localStorage.getItem('counter') || 0
    };
    this.holdState = this.holdState.bind(this);
  }

  holdState() {
    localStorage.setItem('counter', this.state.counter);
    this.setState(prevState => ({
      counter: prevState.counter + 1
    }));
  }

  render() {
    return (
      <div>
        <ul>
          <li>6/5 @ Evergreens</li>
          <li>6/8 vs Kickers</li>
          <li>6/14 @ United</li>
        </ul>
        <div>
          <button onClick={() => this.holdState()}>Click</button>
          <span>{this.state.counter}</span>
        </div>
      </div>
    );
  }
}

export default Schedule;
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400