2017-05-14 12 views
0

私はReactでかなり新しくて助けが必要です。 検索用語に基づいてムービーデータベースからの表示データが必要でした。私はデータを取得するために私のgetMoviesメソッド内のフェッチを使用しています。データはdata.Searchに格納されますが、アクセスする方法と変数に格納する方法はわかりません。フェッチデータの保存方法

class DataService 
{ 
    getMovies (searchTerm) { 
     //let dataStorage; //store somehow data.Search inside 

     fetch("http://www.omdbapi.com/?s=" + searchTerm, { 
      method: 'get' 
     }) 
     .then((resp) => resp.json()) 
     .then(function(data) { 
      return data.Search; 
     }).catch(function(error) { 
      console.log(error);// Error :(
     }); 
    } 
    //return dataStorage; //return data.Search 
} 
+0

コンポーネントの状態で設定しますか? 'fetch'は非同期なので、あなたが戻ったときにデータがフェッチされないかもしれないので、やっているように返すことはできません。 – Li357

+0

[非同期呼び出しからの応答を返すにはどうすればよいですか?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Li357

答えて

1

以下のコードは正しいが、このような単純なように、あなたのケースのためのように反応です:

import React from 'react'; 

export default class DataService extends React.Component { 

    constructor(props) { 
     super(props); 
     this.state = { 
     search_data: [], //for storing videos 
     }; 
     this.getMovies = this.getMovies.bind(this); //bind this function to the current React Component 
    } 

    getMovies (searchTerm) { 
     fetch("http://www.omdbapi.com/?s=" + searchTerm, { 
      method: 'get' 
     }) 
     .then((resp) => resp.json()) 
     .then((data) => { //so that this callback function is bound to this React Component by itself 
      // Set state to bind search results into "search_data" 
      // or you can set "dataStorage = data.Search" here 
      // however, fetch is asynchronous, so using state is the correct way, it will update your view automatically if you render like I do below (in the render method) 
      this.setState({ 
       search_data: data.Search, 
      }); 
     }); 
    } 

    componentDidMount() { 
     this.getMovies(); //start the fetch function here after elements appeared on page already 
    } 

    render() { 
     return (
     {this.state.search_data.map((video, i) =>{ 
      console.log(video); 
      // please use the correct key for your video below, I just assume it has a title 
      return(
       <div>{video.title}</div> 
      ) 
      })}   
     ); 
    } 
} 

ここにあなたが持っている可能性のあるエラーを投稿してお気軽に、感謝

1

Reactで非同期タスクを実行する方法はいくつかあります。最も基本的なものは、setStateを使用し、Promiseをイベントハンドラで起動することです。これは基本的なタスクで実行可能かもしれませんが、後でレースコンディションやその他の不快なものに遭遇します。

これを行うには、サービスでPromiseの結果を返す必要があります。クエリが変更されたときにリアクション側でサービスが呼び出され、新しい結果がフェッチされます。その間、タスクが保留中であることをユーザーに通知するためのロードフラグの設定、およびプロミスがデータを解決または拒否したとき、またはエラーがコンポーネントに格納されているときは、状態遷移はほとんどありません。必要なのは、setStateメソッドです。

さらに高度な技術はReduxredux-thunkまたはredux-sagaミドルウェアに基づいています。 RxJSも考えてみてください。特に、デバウンスやキャンセルなどの機能を備えたこの種のもののために作成されています。

DataServiceを使用した簡単な検索表示の例をご覧ください。

class DataService 
 
{ 
 
    //returns a Promise of search results, let the consumer handle errors 
 
    getMovies (searchTerm) { 
 
    return fetch("http://www.omdbapi.com/?s=" + searchTerm, { 
 
     method: 'get' 
 
    }) 
 
    .then((resp) => resp.json()) 
 
    .then(function(data) { 
 
     return data.Search; 
 
    }) 
 
    } 
 
} 
 

 
const SearchResults = ({data, loading, error}) => 
 
<div> 
 
    { 
 
    data && data.map(({Title, Year, imdbID, Type, Poster}) => 
 
     <div key={imdbID}> 
 
     {Title} - {Year} - {Type} 
 
     <img src={Poster} /> 
 
     </div> 
 
    ) 
 
    } 
 
    {loading && <div>Loading...</div>} 
 
    {error && <div>Error {error.message}</div>} 
 
</div> 
 

 
class SearchExample extends React.Component { 
 
    constructor(props) { 
 
    super(props); 
 
    this.handleChange = this.handleChange.bind(this) 
 
    this.state = { 
 
     data: [], 
 
     loading: false 
 
    }; 
 
    } 
 

 
    handleChange(event) { 
 
    const service = new DataService(); 
 
     
 
    //search query is target's value 
 
    const promise = service.getMovies(event.target.value); 
 
     \t 
 
    //show that search is being performed 
 
    this.setState({ 
 
     loading: true 
 
    }) 
 
     
 
    //after the promise is resolved display the data or the error 
 
    promise.then(results => { 
 
     this.setState({ 
 
     loading: false, 
 
     data: results 
 
     }) 
 
    }) 
 
    .catch(error => { 
 
     this.setState({ 
 
     loading: false, 
 
     error: error 
 
     }) 
 
    }) 
 
    } 
 

 
    render() { 
 
    return (
 
     <div> 
 
     <input placeholder="Search..." onChange={this.handleChange} type="search" /> 
 
     <SearchResults data={this.state.data} loading={this.state.loading} error={this.state.error} /> 
 
     </div> 
 
    ) 
 
    } 
 
} 
 

 
ReactDOM.render(<SearchExample />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 

 
<div id="app"></div>

関連する問題