1

Been pulling my hair for a while now and can't get the dataSource to be updated. I've looked at other posts but can't see why this doesn't work. I've debugged and can see the proper json being returned, so the data is there.

var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});

var ReviewList = React.createClass({
  _getMovieReviews: function() {
    var _urlForReview = this.props.config.api_url + 'movies/' + 
    this.props.movie.id + '/reviews.json?apikey=' + this.props.config.api_key;
            this.setState(function(){
          dataSource: ds.cloneWithRows(['before fetch']);  
        });
    fetch(_urlForReview)
      .then(function(res) {
        return res.json();
      }).then(function (json){
        console.log(json);
        this.setState(function(){
          dataSource: ds.cloneWithRows(['fetch done']);  
        });
    });
  }, 
  getInitialState: function() {
    return {
      dataSource: ds.cloneWithRows(['initial'])
    };
  },
  componentDidMount: function() {
      this._getMovieReviews();
  },

render: function() {
  return (
     {rowData}}
    />
  );
}
});

For now I'm even just trying to update the datasource to anything else than the original value. What am I missing here?

update

Neither "before fetch" or "fetch done" are shown. Only "initial". I'm suspecting that it has to do with that there are other components in the class. Not sure if that could be the case.

update I inserted the sample code one of the answers provided and the sample works in the same view. Super weird. Probably something very stupid I'm missing here...

update It seems the problem lies with updating the datasource from within the fetch statement.

2
  • Aren't you missing setState that will force a rerender? Also, you should keep the render() function pure, as stated in the docs, and instead use the componentDidMount() function. Commented Dec 4, 2015 at 13:34
  • Yeah, I tried that earlier too. Same results, will update my question. Commented Dec 4, 2015 at 14:42

1 Answer 1

2

You need to set it up so that the datasource gets reset on componentDidMount:

  getInitialState: function() {
    return {
      dataSource: ds.cloneWithRows([])
    };
  },

  componentDidMount: function() {
        this._getMovieReviews()  
  },

  _getMovieReviews: function() {
    // Go to api and get movies, then...
    this.setState({
        dataSource: ds.cloneWithRows(movieReviewsFromApi)
    })
  },

Let me know if this answers your question. I've set up a full working project here. The code is also below.

https://rnplay.org/apps/P-em5Q

'use strict';

var React = require('react-native');
var {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  ListView,
} = React;

var movieReviewsFromApi = [
  {name: 'Die Hard', review: 'Best movie ever'}, {name: 'Home Alone 2', review: 'Great movie'}, {name: 'Bourne Identity', review: 'Awesome Movie'}
  ]

var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});

var SampleApp = React.createClass({

  getInitialState: function() {
    return {
      dataSource: ds.cloneWithRows([])
    };
  },

  componentDidMount: function() {
        this._getMovieReviews()  
  },

  _getMovieReviews: function() {
    this.setState({
        dataSource: ds.cloneWithRows(movieReviewsFromApi)
    })
  },

  _renderRow: function(rowData) {
    return (<View style={{height:70,borderBottomColor: '#ededed', borderBottomWidth:1, paddingLeft:10, paddingTop:10}}>
                <Text style={{fontSize:22}}>{rowData.name}</Text>
              <Text style={{color: '#666'}}>{rowData.review}</Text>
            </View> )
  },

  render: function() {
    return (
    <View style={{ marginTop:60 }}>
        <ListView
      dataSource={this.state.dataSource}
      renderRow={this._renderRow}
    />
    </View>
  );
  }
});

AppRegistry.registerComponent('SampleApp', () => SampleApp);
Sign up to request clarification or add additional context in comments.

2 Comments

It's quite weird, still doesn't work. Won't update after initialization.
It seems to have to do with the fetch statement, have you tried your solution with fetch before?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.