1

I am having an issue where previousState is not keeping the data from the previous state every time the state is updated. When I update the state with new data, the previous state is cleared, and only the most recently added data is available.

Here is the first block of code. This fetch request is inside of componentDidMount(), so every time the component is refreshed, it refetches the new data and updates the state:

fetch('/mileage-data')
    .then(res => res.json())
      .then(data => {
        const state = this.state;
        const test = data.data.startingOdo;
        const test2 = data.data.endingOdo;

        if(!state.startingOdometer || !state.startingOdometer) {
          this.setState({ 
            startingOdometer: data.data.startingOdo,
            endingOdometer: data.data.endingOdo
          })
        }

        this.setState(prevState => ({
          startingOdometer: [...prevState, test],
          endingOdometer: [...prevState, test2]
        }))

      })
      .catch(err => {
         console.log(err);
      })

This is what the state looks like:

this.state = {
  startingOdometer: '',
  endingOdometer: ''
}

First, I am checking to see if the initial state is undefined, and if it is, the previous state is omitted and only the new data is added.

My understanding is that you should not mutate state, so using something like push() to make an array doesn't seem to coincide with that. My thought is that by using previous state, I can make a completely new updated version of the state that includes the previous and new data in an array.

Note: I have used Postman to check this /mileage-data GET route and it does send the data back as I expected. So I know there is data being sent back to this fetch request.

This is where I am running into issues:

this.setState(prevState => ({
  startingOdometer: [...prevState, test],
  endingOdometer: [...prevState, test2]
}))

My understanding is that this should create an array, and the spread operator will take all of the contents of the previous array, and combine them with the new data in a new array. But when I console.log out the state after the data is updated, the state only contains the currently added data and does not keep the previous data.

I am sure I am missing something here, or maybe my approach is bad. I have had zero luck hunting through SO. Going on two nights now trying to sort this out! Anyways, thank you in advance!

maison.m
  • 813
  • 2
  • 19
  • 34
  • 1
    "But when I console.log out the state after the data is updated" Where's that happening? I'm not seeing that in your code example. You're probably running into the fact that `setState` does not immediately update state. See [here](https://stackoverflow.com/a/38558319/115049) – rossipedia Jun 15 '18 at 03:55
  • I omitted that along with a couple others for brevity. – maison.m Jun 15 '18 at 14:19

2 Answers2

5

Try:

 this.setState(prevState => ({
      startingOdometer: [...prevState.startingOdomoter, test],
      endingOdometer: [...prevState.endingOdometer, test2]
    }))

Also, you may be losing context of the this keyword in the promise. Try putting let that = this above the fetch call, and use that.setState if it still isn't working.

Jordan Daniels
  • 4,896
  • 1
  • 19
  • 29
0

I'm assuming data.data.startingOdo is an object. It dosen't make sense that you are setting it to an object sometimes and array others.

From what I see you just need to keep adding new data into the array. Why not this?

Also if you are needing state to persist when a component is un-mounted and re-mounted you need to look at some type of global state management like redux.

// set initial state to empty arrays
state = {
  startingOdometer: [],
  endingOdometer: [],
}

fetch('/mileage-data')
.then(res => res.json())
  .then(data => {
    const {startingOdometer, endingOdometer} = this.state;

    this.setState({ 
      startingOdometer: [...startingOdometer, data.data.startingOdo],
      endingOdometer: [...endingOdometer, data.data.endingOdo],
    })

  })
  .catch(err => {
     console.log(err);
  })
jlemm45
  • 127
  • 1
  • 6
  • 'Persist'. That's the word I have been looking for. I need the state to persist throughout the entire user's session, and then when they logout, the data in the state will be saved to a database. I am not so familiar with Redux, so this may just be a case of me not being aware of when I should use Redux. – maison.m Jun 15 '18 at 14:39