【问题标题】:Getting server data with AJAX in React在 React 中使用 AJAX 获取服务器数据
【发布时间】:2017-04-26 18:10:37
【问题描述】:

我正在尝试进行 AJAX 调用以将服务器数据导入我的 React 组件。

我无法使用 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 } ] 

为什么会出现这个错误?又该如何实施?

【问题讨论】:

  • @AndyRay 我的 get 请求应该在我的初始状态函数中吗?

标签: javascript jquery ajax node.js reactjs


【解决方案1】:

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 请求,并将结果存储在 state 中而不是 props 中。

【讨论】:

  • 您能否详细说明在 componentDidMount 生命周期方法中执行请求的优势是什么?
  • 嗯,很奇怪,我仍然收到 Uncaught TypeError: Cannot read property 'map' of undefined error
  • 在 get 回调中记录 data 以确保它已被填充。
  • 好吧,我实际上没有收到 TypeError,但它看起来没有填充。
  • 一定要绑定吗?回复:stackoverflow.com/questions/39720791/…
【解决方案2】:
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。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-24
    • 2023-03-17
    • 2013-03-18
    • 1970-01-01
    • 2014-05-20
    • 2016-06-15
    相关资源
    最近更新 更多