2017-07-26 5 views
0

私はReactで手を汚しています。 ReactJSを使用してwikipedia viewerプロジェクトを書くことに決めました。しかし、Reactコンポーネントを使ってwikipediaのAPIからデータを取得した後、私は昨日レンガの壁に当たった。そして、私はそれが非同期呼び出しと関係があると思います。非同期呼び出しに反応する際にAPIを使用するにはどうすればよいですか?

私は、クエリを取り込み、APIのURLにそれを注入定数定義された:その後、私はComponentDidMount状態で非同期APIをフェッチするクラスを定義し javascript const apiUrl = query => `https://crossorigin.me/https://en.wikipedia.org/w/api.php?action=opensearch&format=json&search=${query}` を:

class Wiki extends React.Component { 
constructor(props){ 
    super(props); 
    console.log('Inside Constructor') 
} 
componentWillMount(){ 
    this.setState = { 
    wikiData: undefined 
    } 
    console.log('Before fetch') 
    fetch(apiUrl(this.props.query)) 
    .then(console.log('fetch successful')) 
    .then(response => { 
     if(!response.ok){ 
      throw Error("Response not ok") 
     } 
     return response 
    }) 
    .then(data => data.json()) 
    .then(data => { 
     this.setState ={ 
      wikiData: data 
     } 
     console.log(data) 
    }) 

} 
render(){ 
    if(!this.state.wikiData == null) return <p>No answer</p> 
    else{ 
    return (
     <div> 
      <h1>Something happened</h1> 
     <h2>{this.state.wikiData[0]}</h2> 
     </div> 
    ) 
    } 
} 

}

私はこれをアプリケーションコンポーネントで呼び出すと、データがコールから返され、nullではなくなったが、レンダリングが中断する原因となるTypeErrorが「ヌルのプロパティ 'wikiData'を読み取れません」というメッセージが表示されます。 Console messaqges 代わりにcomponentDidMountを使用しようとしましたが、どちらも動作しません。 私は何をすべきか分かりません。私はこのプロセスを理解したいと思います。 は、ここに私のcodepenです: https://codepen.io/Banhawy/pen/eEmQBW?editors=1010

私はレンダリングする前にそれにアクセスして処理できるように、APIの呼び出しがデータで返された後にのみコンポーネントをレンダリングする方法を知りたいです。

答えて

0

私はあなたのコードを少し修正し、あなたを助けてくれるコメントをいくつか出しました。

class Wiki extends React.Component { 

    constructor(props) { 
    super(props); 

    // this.state, not this.setState. 
    // Also, it helps if you set your initial value to the value 
    // to what you expect from your fetch (ie an array, albeit empty) 
    this.state = { wikiData: [] } 
    } 

    // componentDidMount rather than componentWillMount 
    // https://daveceddia.com/where-fetch-data-componentwillmount-vs-componentdidmount/ 
    componentDidMount() { 
    fetch(apiUrl(this.props.query)) 
     .then(response => { 
     .then(data => data.json()) 
     .then(data => this.setState = { wikiData: data } 
     }); 
    } 

    render() { 

    // Check to see if your initial state is empty or not 
    if (!this.state.wikiData.length) return <p>No answer</p> 

    // No need for your else here. If your state is not empty, the first 
    // return doesn't run, but this one does as a default. 
    return (
     <div> 
     <h1>Something happened </h1> 
     <h2>{this.state.wikiData[0]}</h2> 
     </div> 
    ) 
    } 

} 
+0

「api」が解決されるまでに別のルートに移動したため、このコンポーネントがアンマウントされた場合はどうなりますか? 'this.setState'は、アンマウントされたcomponent__に対して状態を設定することを__tryingすることを失敗します。これらのシナリオをどのように扱うのですか? – guleria

0

componentWillMountに入力ミスがあり、this.stateの代わりにthis.setStateを書きました。私はまた、コンストラクタにこの宣言を移動するために、あなたに助言:

class Wiki extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { 
     wikiData: undefined 
    } 
    } 
    ... 
} 
0

サービスは、任意の応答に答え前にrenderメソッドが呼び出されたことを言ったときにあなたが正しいです。

wikiDataフィールドが未定義である間にローディングスピナーなどを表示してレンダリングを条件付けし、サービスがデータを返すときにwikiDataをレンダリングする必要があります。

0

あなたのコードにはいくつかの誤りがあります。

まず、クラスのコンストラクタにコンポーネントのデフォルト状態を設定する必要があります。そのため、メソッドのcomponentWillMountメソッドの最初の3行を移動します。

第二には、デフォルトの状態が間違っている:

this.setState = { 
    wikiData: undefined 
} 

this.setStateあなたがthis.stateを使用する必要があり、デフォルトの状態を設定するために、機能です。

関連する問題