无法弄清楚如何使用{this.props.etc},特别是使用React.js中的map

时间:2015-06-24 22:29:08

标签: javascript reactjs react-jsx

var Order = React.createClass({
  loadOrderFromServer: function() {
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      cache: false,
      success: function(data) {
        console.log(data);
        this.setState({data:data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },  
    getInitialState: function() {
      return {data: []};
    },
    componentDidMount: function() {
      this.loadOrderFromServer();
      setInterval(this.loadOrderFromServer, this.props.pollInterval);
    },
    render: function() {
      return (
        <div className="orderInformationTable">
        <table>
          <thead>
            <tr>
              <th width="200">General Info</th>
              <th> </th>
            </tr>
         </thead>
         <tbody>    
           <OrderInformationTable order={this.state.data.order} />
         </tbody>
       </table>  
       </div>
      );  
     }
   });



var OrderInformationTable = React.createClass({
  render: function() {

 var orderInfo = this.props.order.map(function (info) {
   return ( 
     <tr>
       <td>{info.attribute}</td>  
       <td>{info.value}</td> 
     </tr>
   )
 });

  return (
    <div className="orderInfoTableContents">
      {orderInfo}
    </div>  
  );
 }
});

    React.render(
    <Order url="api_url" pollInterval={2000} />,
    document.getElementById('order')
    );

//来自api的数据格式如下

{
"order":[
  {"attribute":"id","value":2066},
  {"attribute":"name","value":"John D."},
  {"attribute":"location","value":"USA"},
],
"pieces":[
{"id":2,"type":"Diamond Ring","status":null,
  "items":[
  {"id":3,"type":"setting","style":"solitaire"},   
  {"id":2,"type":"setting","style":"style 3"}  ],
"tasks":[
  {"number":1,"task":"order diamond","description":"for diamond 43","status":"in progress"}  ]
} <-- end of a single "piece"
] <-- end of array of "pieces"
} 

我得到的错误是: TypeError:this.props.order未定义

我成功地使用静态虚拟数据完成了这一切,其中一切都是道具,但现在我使用状态,它不起作用,我无法弄清楚错误。

另外,我可以访问OrderInformationTable中的this.props.order来显示它,但我无法对它做任何事情。因此,我不确定我理解这个物体的本质是什么。我确定来自api和this.state.data的数据是正确的。提前感谢任何能够阐明这一点的人!

1 个答案:

答案 0 :(得分:1)

正如我在评论中所说,OrderInformationTable ajax请求完成之前呈现,这导致在开始时没有道具传递给这个子组件。

可能解决此问题的一种方法是:

var OrderInformationTable = React.createClass({
  render: function() {
  var orderInfo;
  if (this.props.order) {

    orderInfo = this.props.order.map(function (info) {
      return ( 
        <tr>
          <td>{info.attribute}</td>  
          <td>{info.value}</td> 
        </tr>
      )
    });
  }
  return (
    <div className="orderInfoTableContents">
      {orderInfo}
    </div>  
  );
 }
});

这是它的工作原理:
- React Components有lifecycles。您正在使用代码执行的操作是等待组件安装,然后启动ajax请求(顾名思义)异步。
那么会发生什么? 好吧,您的组件已安装,此时data中没有state,因此您不会向OrderInformationTable发送任何内容,因此当您尝试map到{{1}时并且发生错误,因为在此点没有this.props.order。如果您避免此错误,通过检查是否已定义this.props.order或以其他任何方式来避免此错误,您将是安全的,因为在 ajax请求完成后,您将获得{{1} },您的州将通过this.props.order传递给data,您的组件将更新并呈现您的新内容。

希望这能让你大吃一惊。