2016-12-11 3 views
1

私はReactコンポーネントにサーバーデータを取得するためにAJAX呼び出しをしようとしています。ReactでAJAXを使用してサーバーデータを取得する

Reactで表示できません。私はこのエラーを取得:

Uncaught TypeError: Cannot read property 'map' of undefined 

私は研究http://andrewhfarmer.com/react-ajax-best-practices/reactjs - Uncaught TypeError: Cannot read property 'map' of undefinedを行ってきた。しかし、私は私の反応コンポーネントにマップするかどうかはわかりません。ここで

は、以下の私のコードです:

var items; 
$.get("http://localhost:3000/getProducts", function(data) { 
    items = data; 
    this.state.items = data; 
}); 

/*React Code Below */ 
var RepeatModule = React.createClass({ 
    getInitialState: function() { 
     return { items: [] } 
    }, 
    render: function() { 
     var listItems = this.props.items.map(function(item) { 
     return (
      <div className='brick'> 
       <div> 
        <a target='_blank' href={item.productURL}><img src={item.imageURL}/></a> 
        <p className='itemName'>Short Sleeve Oxford Dress Shirt, White, Large</p> 
        <p className='storeName'>Nike Factory Store</p> 
        <img className='foundPicture' src='../images/rohit.png'/> 
       </div> 
      </div> 
     ); 
     }); 

     return (
     <div> 
      {listItems} 
     </div> 
    ); 
    } 
}); 

ReactDOM.render(<RepeatModule items={items} />,    
    document.getElementById('clothing-content')); 

項目のプロパティを持つ私のJSON配列は有効です。

[ { _id: 584d1e36a609b545b37611ac, 
    imageURL: 'http://ih1.redbubble.net/image.252113981.3904/ra,unisex_tshirt,x1350,fafafa:ca443f4786,front-c,30,60,940,730-bg,f8f8f8.u2.jpg', 
    productName: 'Drake', 
    productType: 'T-Shirts & Hoodies', 
    price: '$29.97', 
    productURL: 'http://www.redbubble.com/people/misfitapparel/works/22923904-drake?grid_pos=6&p=t-shirt', 
    __v: 0 } ] 

なぜこのエラーが発生している:

ここでは、以下の配列がありますか?そしてそれはどのように実装すべきでしょうか?

+0

@AndyRay私の取得要求は私の初期状態の機能にあるべきですか? –

答えて

0

Javascriptは非同期です。 get関数コールバックはプログラムの流れをブロックせず、後で実行します。残りのコードは引き続き実行されます。 AJAXリクエストを非同期的に送信すると、未定義の変数を持つ反応コンポーネントがレンダリングされます。その後、get要求が完了し、データが取り込まれますが、レンダリングが完了してから時間がかかります。

ここで最も簡単な解決策は、あなたのAJAXリクエストが終了した後成分のみをレンダリングすることです:

var RepeatModule = React.createClass({ 
    render: function() { 
     var listItems = this.props.items.map(function(item) { 
      return (
       <div className='brick'> 
       <div> 
        <a target='_blank' href={item.productURL}><img src={item.imageURL}/></a> 
        <p className='itemName'>Short Sleeve Oxford Dress Shirt, White, Large</p> 
        <p className='storeName'>Nike Factory Store</p> 
        <img className='foundPicture' src='../images/rohit.png'/> 
       </div> 
       </div> 
      ); 
     }); 

     return (
      <div> 
       {listItems} 
      </div> 
     ); 
    } 
}); 

$.get("http://localhost:3000/getProducts", function(data) { 
    ReactDOM.render(<RepeatModule items={data} />, 
     document.getElementById('clothing-content')); 
}); 

より良い解決策は、あなたのニーズに応じて、componentDidMountライフサイクルメソッドにAJAX要求を行うにはおそらく、結果を小道具の代わりに州に格納します。

+0

componentDidMountライフサイクルメソッドでリクエストを実行する利点は何ですか? –

+0

奇妙なことに、未知の型をまだ取得しています。エラー:未定義のエラーのマップ 'を読み取れません。 –

+0

getコールバックに 'data'を記録して、データが入力されていることを確認してください。 –

0
var RepeatModule = React.createClass({ 
    getInitialState: function() { 
     return { items: this.props.items || [] } 
    }, 
    componentWillMount: function() { 
    console.log("componentWillMount()") 
    $.get("http://localhost:3000/getProducts", function(data) { 
     this.setState({ items : data }) 
     console.log(data,"data is here"); 
     }.bind(this)); 
    }, 
    render: function() { 
     var listItems = this.state.items.map(function(item) { 
     return (
      <ListItem item={item}/> 
     ); 
     }); 

     return (
     <div> 
      {listItems} 
     </div> 
    ); 
    } 
}); 
/* make the items stateless */ 
var ListItem = function(props) { 
    return (
     <div className='brick' key={props.item._id}> 
     <div> 
      <a target='_blank' href={props.item.productURL}><img src={props.item.imageURL}/></a> 
      <p className='itemName'>Short Sleeve Oxford Dress Shirt, White, Large</p> 
      <p className='storeName'>Nike Factory Store</p> 
      <img className='foundPicture' src='../images/rohit.png'/> 
     </div> 
     </div> 
    ); 
} 
var data = [] 
ReactDOM.render(<RepeatModule items={data} />, document.getElementById('clothing-content')); 

私はデータをバインドし、componentWillMountを使用しなければなりませんでした。

関連する問題