问题
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
回答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
回答2:
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] });
}
}
回答3:
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
来源:https://stackoverflow.com/questions/43988008/react-native-child-listview-will-not-update-after-element-in-parent-is-changed