2016-08-16 67 views
0

我試圖刷新listview時執行componentWillReceiveProps。看起來dataSource在獲取後更新(我將console.log(this.state.dataSource)放在render()中並且它根據端點的當前狀態而更改)。dataSource被更新,但listview沒有刷新組件後的react-native nativeWillReceiveProps

但是,ListView保持不變。我想知道爲什麼,並懷疑dataSource。所以我最終使得string對象在render()中打印出dataSource。 var str = JSON.stringify(this.state.dataSource._dataBlob.s1);

而且<View><Text>{str}</Text>

componentWillReceiveProps()被執行時將上述部分的變化。但是,listview保持不變。我不知道爲什麼會發生這種情況。

這是我的代碼的片段。

componentWillReceiveProps(){ 
    var query = ApiUrl.urlForWeekInfo(this.state.email); 
    console.log(query); 
    this._executeQuery(query,3); 
    } 


    constructor(props) { 
    super(props); 

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

     this.state = { 
     isLoading: false, 
     ... 
     first_name: this.props.first_name, 
     email: this.props.email, 
     dataSource: dataSource.cloneWithRows(this.props.listings)  
    }; 
    } 
.. 

_executeQuery(query,i) { 

    this.setState({ isLoading: true }); 
    fetch(query) 
     .then(response => response.json()) 
     .then(json => this._handleResponse(json.response,i)) 
     .catch(error => 
     this.setState({ 
      isLoading: false, 
      message: 'Something bad happened ' + error 
    })); 
    } 

    _handleResponse(response,i) { 
    this.setState({ isLoading: false , message: '' }); 
    if (response.application_response_code.substr(0, 1) === '1') { 
     if(i==1){ 
     this.props.navigator.push({ 
      title: 'Apply', 
      component: Apply, 
      passProps: {listings: response.listings, times: response.timetable, week_num: this.state.week_num} 
     }); 
     } else if (i==3){ 

     var output = response.listings; 
     this.setState({ 
      dataSource: this.state.dataSource.cloneWithRows(output) 
     }); 

     console.log(response.listings); 
     this.forceUpdate(); 

     } 
    } else { 
    } 
    } 

render() { 

    console.log(this.state.dataSource._dataBlob.s1); 

    var str = JSON.stringify(this.state.dataSource._dataBlob.s1); 
    var listviewsource = this.state.dataSource; 

    return (

    <View style={[this.border('red'), styles.container_top]}> 
     <View style={[this.border('black'), styles.container_top_buttons]} > 

     <ListView 
      dataSource={listviewsource} 
      renderRow={this.renderRow.bind(this)}/> 

     </View>  
     {spinner} 
     <View> 
     <Text>{str}</Text> 
     </View> 

    </View> 




     ); 
     }} 

請分享你可能有的任何想法或經驗。


我最終找到針對此問題的解決方案:

var array = response.listings; 
    var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 
    //=> call another ds variable. 

    this.setState({ 
     rawData: array, 
     dataSource: ds.cloneWithRows(response.listings) 
    }); 

回答

1

有更新的行到你的ListView沒有直接的方法。在那裏沒有太多的文件ListView.DataSource。所以這裏它去 -

如果你想添加/ append/prepend /更新/刪除行從一個ListView,你只需要更新數據源並調用setState中的cloneWithRows()。

例如,我想從URL中獲取數據。每次點擊「加載更多」時,我會將新行添加到我的數據源中。

getInitialState: function(){ 
    return { 
     rawData: [], 
     dataSource: new ListView.DataSource({ 
      rowHasChanged: (row1, row2) => row1 !== row2 
     }), 
     loaded: false, 
     page: 1, 
    } 
}, 

在第一次投票,我呼籲在ComponentDidMount此功能(),它填充的ListView我與初始數據和「網頁」 = 1的狀態。

reloadData: function(){ 
    this.setState({ loaded: false, rawData: [], page: 1 }); 

    API.getUpcomingMovies(this.state.page) 
     .then((data) => { 
      this.setState({ 
      rawData: this.state.rawData.concat(data), 
      dataSource: this.state.dataSource.cloneWithRows(this.state.rawData.concat(data)), 
      loaded: true, 
      }); 
     }); 
    }, 

每當我點擊「加載更多」從API獲取JSON時,我會調用以下函數。每次點擊「加載更多」時,「頁面」會增加。正如你所看到的,我將我的rawData [](這是一個包含JSON對象的簡單數組)連接起來。如果你想新的數據預先考慮到您的RAWDATA,你可以不喜歡這個 -

this.setState({ 
    rawData: data.concat(this.state.rawData) 
)} 
+0

就我而言,我沒有來連接或預先準備,但完全重裝所有的東西。即使我用cloneWithRows語句觸及dataSource,它也不適用於我。我試圖使用'新的ListView',它開始工作!你會建議採取這種方式的消極方面? –

+0

@SungpahLee真的沒什麼!你所做的與我的片段基本相同。我在'getInitialState()'中有'new ListView',並且在'constructor()'中有相同的。所以海事組織我認爲這種方法沒有任何不利之處。但是,其他意見是值得歡迎的。此外,您可以直接替換數據而不是串聯。 Gist比這些原始的操作重要。記住,如果你想重新渲染數據,你只需要通過調用'cloneWithRows(newdata)'來更新state.dataSource。 – Mihir