0

I can't seem to get my ListView to update.

I have a parent container with a toggle switch (<SegmentedControls />). When the user clicks that toggle switch I'd like the ListView in the child component to update using the updated reservationListSelectedOption state value.

What am I missing?

Code here: https://gist.github.com/chapeljuice/69483ab0bde13346de024d4e4a9753f0

chapeljuice
  • 856
  • 1
  • 11
  • 21

3 Answers3

1

Actually, there's something wrong in the way you set your dataSource, in your constructor, you set it for the first time with: new ListView.DataSource({}) (this should not be changed later, because this is just kind of dummy thing, no data passed to it yet)

However, later you reset that state with : dataSource: this.state.dataSource.cloneWithRows(reservationData.previous)

=> (Here it has the cloneWithRows, so it will have data now => which means the this.state.dataSource "dummy-frame" itself has been changed, and the next execution of .cloneWithRows will fail - will not have the .cloneWithRows function anymore)

======> SOLUTION:

In my opinion, you can do:

In cardList.js:

// Put the data-source ds here, which won't be changed
var ds = new ListView.DataSource({rowHasChanged: (row1, row2) => row1 !== row2});

class CardList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      reservationListStatus: this.props.reservationListStatus,
      dataSource: ds.cloneWithRows(/* PUT YOUR INITIAL reservationData, OR JUST a blank array '[]' will be fine*/),
    };
  }

..and later on, you just need to use ds.cloneWithRows(YOUR_NEW_RESERVATION_DATA) (always keep the ds unchanged), something like this:

  getReservationData() {
    if ( this.props.reservationListStatus === "Previous Reservations" ) {
      this.setState({
        dataSource: ds.cloneWithRows(reservationData.previous)
      })
    } else {
      this.setState({
        dataSource: ds.cloneWithRows(reservationData.current)
      })
    }
    console.log(this.state)
  }

That is the way you should do, but if it doesn't work yet, please post here some errors you encounter, thanks

thinhvo0108
  • 2,212
  • 1
  • 13
  • 23
  • That does make more sense to me so I did switch out my code (and updated my gist in the original question), however my ListView is still not updating. I have that console.log in there that outputs `this.state.reservationListStatus` and no matter which tab option I press the console always outputs "Current Reservations", and never outputs "Previous Reservations". – chapeljuice May 16 '17 at 15:58
0

Try adding componentWillReceiveProps to your child component. It would look something like this:

  componentWillReceiveProps(nextProps) {
    if (this.props.options !== nextProps.options) {
      this.setState({ reservationListSelectedOption: nextProps.options[0] });
    }
  }
Matt Aft
  • 8,742
  • 3
  • 24
  • 37
  • Hrm, thanks but that didn't seem to do anything (that I could tell). I'd also want to make sure the state was set dynamically and not use a static option like you have. I'll look into `componentWillReceiveProps` though! – chapeljuice May 15 '17 at 21:36
0

Actually I found a solution, thanks to both thinhvo0108 and Matt Aft for helping me get there.

Here is my revised componentWillReceiveProps function, which combined with fixed dataSource is now updating the ListView correctly:

componentWillReceiveProps (nextProps) {
  if ( nextProps.reservationListStatus === "Past Reservations" ) {
    this.setState({
      dataSource: ds.cloneWithRows(reservationData.previous)
    })
  } else {
    this.setState({
      dataSource: ds.cloneWithRows(reservationData.current)
    })
  }
  console.log( 'nextProps.reservationListStatus: ' + nextProps.reservationListStatus );
}

I updated my gist as well with the working code: https://gist.github.com/chapeljuice/69483ab0bde13346de024d4e4a9753f0

Community
  • 1
  • 1
chapeljuice
  • 856
  • 1
  • 11
  • 21