2016-10-09 17 views
0

私は一日のソリューションを探していましたが、私は多くを学んだが、何が間違っているのか分からなかった。ここで私がすること:ネイティブで反応しますthis.setState()はフェッチ関数の状態を変更しません

  1. Appコンストラクタの呼び出し。場合コンポーネントマウント
  2. 状態ローディング、データソースとデータを初期化、プログラムはのgetData関数は非同期に、データをJSON
  3. に変換される機能
  4. フェッチ要求されたURL
  5. とのgetData関数を呼び出しJSONがクローニングされてwebviewのデータブラブになりました
  6. 次に、読み込みとデータを変更してsetState関数が呼び出されます。

これは、setStateが起動しない場所です。レンダリングさえできません(それはすべきです)。すべてのチュートリアルでは、すべてのフォーラムで、この方法(およびそれも論理的)であることが示されています。ここで

はコードです:

import Exponent from 'exponent'; 
import React from 'react'; 
import { 
    StyleSheet, 
    Text, 
    View, 
    ListView, 
    ActivityIndicator 
} from 'react-native'; 

import { Button, Card } from 'react-native-material-design'; 
import {UnitMenuCard} from './unitmenucard.js'; 

class App extends React.Component { 
    constructor(props) { 
    super(props); 
    const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 
    this.state = { 
     loading: true, 
     dataSource: ds, 
     data: null 
    } 
    } 

    componentDidMount() { 
    //console.log('componentDidMount'); 
    this.getData('https://dl.dropboxusercontent.com/u/76599014/testDATA.json'); 
    } 

    getData(url) { 
    console.log('loading data'); 
    return fetch(url).then(
     (rawData) => { 
     console.log('parsing data'); 
     //console.table(rawData); 
     return rawData.json(); 
     } 
    ).then(
     (jsonData) => 
     { 
     console.log('parsing to datablobs'); 
     let datablobs = this.state.dataSource.cloneWithRows(jsonData); 
     console.log('datablobs: ' + datablobs); 
     return datablobs; 
     } 
    ).then(
     (datablobs) => { 
      console.log('setting state'); 
      this.setState = ({ 
      loading: false, 
      data: datablobs 
      }); 
      console.log('the loading is ' + this.state.loading); 
      console.log('the data is ' + this.state.data); 
     } 
    ).catch((errormsg) => 
     {console.error('Loading error: ' + errormsg);} 
    ); 
    } 

    render() { 
    console.log('loading is ' + this.state.loading); 
    var dataToDisplay = ''; 
    if(this.state.loading) { 
     dataToDisplay = <ActivityIndicator animated={true} size='large' /> 
    } else { 
     //let jdt = this.state.dataSource.cloneWithRows(this.state.data); 
     dataToDisplay = <ListView 
     dataSource={this.state.ds} 
     renderRow={(unit) => <UnitMenuCard name={unit.name} image={unit.picture} menu={unit.menu}/>} 
     /> 
    } 
    return (
     <View style={styles.container}> 
     {dataToDisplay} 
     </View> 
    ); 
    } 
} 

const styles = StyleSheet.create({ 
    container: { 
    flex: 1, 
    backgroundColor: '#fff', 

    }, 
}); 

Exponent.registerRootComponent(App); 

は、私が何かを逃しましたか?あなたの答えは強力なスタックオーバーフローありがとうございます。

答えて

0

私はあなたがDatSourceがどのように動作するのか誤解していると思います。

getInitialState: function() { 
    var ds = new ListViewDataSource({rowHasChanged: this._rowHasChanged}); 
    return {ds}; 
}, 
_onDataArrived(newData) { 
    this._data = this._data.concat(newData); 
    this.setState({ 
    ds: this.state.ds.cloneWithRows(this._data) 
    }); 
} 

これは、ここではドキュメントから取得されます:https://facebook.github.io/react-native/docs/listviewdatasource.html

はあなたの状態でお使いのデータソースオブジェクトのクローンを作成する必要があるかを参照してください。重要なことは、cloneWithRowsに、API(お客様のケースではjsonData)から返されたデータを渡すことです。これにより、取得したデータを含むクローンデータソースが作成されます。

代わりにコードでは、データソースのクローンを作成するだけですが、ビューがリンクされている実際のものを置き換えることはありません。あなたはそれをこのように実行する必要があります。あなたはこのためstate.dataを必要としない

.then(
    (datablobs) => { 
     console.log('setting state'); 
     this.setState = ({ 
     loading: false, 
     dataSource: datablobs 
     }); 
     console.log('the loading is ' + this.state.loading); 
     console.log('the data is ' + this.state.data); 
    } 

を、リストビューは、データソースオブジェクトから読み込みます。また、すべてを1つで行うだけで、2つの.thenコールを回避することもできます。

また別の問題があります。状態の間違ったプロパティにリンクされたリストビューがあります。あなたは、データ・ソース・オブジェクトを格納場所

dataToDisplay = <ListView 
    dataSource={this.state.dataSource} 
    renderRow={(unit) => <UnitMenuCard name={unit.name} image={unit.picture} menu={unit.menu}/>} 
    /> 

this.state.dataSourceがある:あなたがする必要がありますレンダリングでビューのコードをリストします。

+0

ありがとうございます。出来た。 –

0
dataToDisplay = <ListView 
     dataSource={this.state.ds} // <- you set the dataSource to this.state.ds instead of this.state.data 
     renderRow={(unit) => <UnitMenuCard name={unit.name} image={unit.picture} menu={unit.menu}/>} 
     /> 

データソースは、フェッチコールから取得したデータである必要があります。したがって、dataSourceはthis.state.dataに等しく設定する必要があります。

+0

それはafaikの唯一の問題ではありません。彼はまた、州のデータソースをクローンした新しいものに置き換えることもしていません。下の私の答えを見てください。 –

関連する問題