2016-05-31 81 views
0

我想實現一個處理到服務器的Ajax請求並將數據傳遞給兩個子組件的組件。但是,似乎ajax調用從來沒有被制定。React組件不會發出Ajax調用

Feed.js:237 Uncaught TypeError: Cannot read property 'data' of null 

是我得到的錯誤。

// Parent component containting feed and friends components, 
// handles retrieving data for both 

import React, { Component } from 'react' 
import FeedBox from './Feed.js' 
import FriendsBox from './Friends' 

const config = require('../../config') 

export default class FrontPage extends Component { 
    constructor(props) { 
     super(props) 
     this.state = { 
      data: {}, 
      pollInterval: config.pollInterval 
     } 
     this.loadDataFromServer = this.loadDataFromServer.bind(this) 
    } 

    loadDataFromServer() { 
     $ajax({ 
      url: config.apiUrl + 'frontpage', 
      dataType: 'jsonp', 
      cache: false, 
      success: (data) => { 
       this.setState({data: data}) 
       console.log(data) 
      }, 
      error: (xhr, status, err) => { 
       console.error(this.url, status, error.toString()) 
      } 
     }) 
    } 
    componentDidMount() { 
     this.loadDataFromServer() 
     setInterval(this.loadDataFromServer, this.state.pollInterval) 
    } 
    componentWillUnmount() { 
     this.state.pollInterval = false 
    } 
     render() { 
      return (
       <div className="FrontPage"> 
        <FeedBox data={ this.state.data.feedData } /> 
        <FriendsBox data={ this.state.data.friendsData } /> 
       </div> 
       ) 
     } 
    } 

編輯:

這裏是進料組件的代碼,它被傳遞道具從其父FrontPage中的兩個子組件之一

import React, { Component } from 'react'; 

var config = require('../../config') 

class Thread extends Component { 
    rawMarkup() { 
    var rawMarkup = marked(this.props.children.toString(), { sanitize: true }) 
    return {__html: rawMarkup } 
    } 

    render() { 
    return (
     <div className="thread"> 
     <h4 className="threadVictim">Dear {this.props.victim}: </h4> 
     <span dangerouslySetInnerHTML={this.rawMarkup()} /> 
     <p>signed,</p> 
     <div>{this.props.author} and {this.props.ct} others.</div> 
     <hr></hr> 
     </div> 
    ) 
    } 
} 

class ThreadList extends Component { 
    render() { 
    var threadNodes = this.props.data.map(function (thread) { 
     return (
     <Thread victim={ thread.victim } author={ thread.author } ct={ thread.included.length } key={ thread._id }> 
      { thread.text } 
     </Thread> 
    ) 
    }) 
    return (
     <div className="threadList"> 
     { threadNodes } 
     </div> 
    ) 
    } 
} 

var ThreadForm = React.createClass({ 

    getInitialState: function() { 
    return {author: '', 
      text: '', 
      included: '', 
      victim: '', 
      ct: '' 
      } 
    }, 
    handleAuthorChange: function (e) { 
    this.setState({author: e.target.value}) 
    }, 
    handleTextChange: function (e) { 
    this.setState({text: e.target.value}) 
    }, 
    handleIncludedChange: function (e) { 
    this.setState({included: e.target.value}) 
    }, 
    handleVictimChange: function (e) { 
    this.setState({victim: e.target.value}) 
    }, 
    handleSubmit: function (e) { 
    e.preventDefault() 
    var author = this.state.author.trim() 
    var text = this.state.text.trim() 
    var included = this.state.included.trim() 
    var victim = this.state.victim.trim() 
    if (!text || !author || !included || !victim) { 
     return 
    } 
    this.props.onThreadSubmit({author: author, 
           text: text, 
           included: included, 
           victim: victim 
           }) 
    this.setState({author: '', 
        text: '', 
        included: '', 
        victim: '', 
        }) 
    }, 
    render: function() { 
    return (
    <form className="threadForm" onSubmit={this.handleSubmit}> 
     <input 
     type="text" 
     placeholder="Your name" 
     value={this.state.author} 
     onChange={this.handleAuthorChange} /> 
     <input 
     type="text" 
     placeholder="Say something..." 
     value={this.state.text} 
     onChange={this.handleTextChange} /> 
     <input 
     type="text" 
     placeholder="Name your victim" 
     value={this.state.victim} 
     onChange={this.handleVictimChange} /> 
     <input 
     type="text" 
     placeholder="Who can see?" 
     value={this.state.included} 
     onChange={this.handleIncludedChange} /> 
     <input type="submit" value="Post" /> 
    </form> 
    ) 
    } 
}) 

var ThreadsBox = React.createClass({ 
    // loadThreadsFromServer: function() { 
    // $.ajax({ 
    //  url: config.apiUrl + 'feed', 
    //  dataType: 'jsonp', 
    //  cache: false, 
    //  success: function (data) { 
    //  this.setState({data: data}) 
    //  }.bind(this), 
    //  error: function (xhr, status, err) { 
    //  console.error(this.url, status, err.toString()) 
    //  }.bind(this) 
    // }) 
    // }, 
    handleThreadSubmit: function (thread) { 
    var threads = this.state.data 
    var newThreads = threads.concat([thread]) 
    this.setState({data: newThreads}) 
    $.ajax({ 
     url: config.apiUrl + 'threads', 
     dataType: 'json', 
     type: 'POST', 
     data: thread, 
     success: function (data) { 
     this.setState({data: data}) 
     }.bind(this), 
     error: function (xhr, status, err) { 
     this.setState({data: threads}) 
     console.error(this.url, status, err.toString()) 
     }.bind(this) 
    }) 
    }, 
    // getInitialState: function() { 
    // return {data: [], 
    //   pollInterval: config.pollInterval} 
    // }, 
    // componentDidMount: function() { 
    // this.loadThreadsFromServer() 
    // setInterval(this.loadThreadsFromServer, this.state.pollInterval) 
    // }, 
    // componentWillUnmount: function() { 
    // this.state.pollInterval = false; 
    // }, 
    render: function() { 
    return (
    <div className="threadsBox"> 
     <div className="feedNav"> 
     <h1>Home</h1> 
     <h1>Heat</h1> 
     </div> 
     <ThreadList data={ this.state.data } /> 
     <ThreadForm onThreadSubmit={ this.handleThreadSubmit } /> 
    </div> 
    ) 
    } 
}) 

module.exports = ThreadsBox 
+0

'setInterval(this.loadDataFromServer,this.state.pollInterval)'看起來不對。哪一行是錯誤的行? –

+0

最初,你的'this.state.data'是一個空數組,但你試圖在'render'函數中訪問'this.state.data.feedData',這意味着你期待它成爲一個對象。也許讓國家結構更加清晰和一致。 – Kujira

+0

@Kujira謝謝,我沒有注意到,以前我正在返回一個數組,現在它確實是一個對象。我將其更改爲data = {},但出現相同的錯誤 –

回答

2

您需要在ThreadsBox中定義初始狀態對象,因此它不是null

var ThreadsBox = React.createClass({ 
    getInitialState: function() { 
     return { 
     data: {} 
     }; 
    } 
    // ... 
}) 
module.exports = ThreadsBox 
+0

通過閱讀錯誤,你可以得出這個結論。 '不能讀取'null'的屬性'data'意味着'data'之前的任何內容都不存在,不管它是'this.props.data'還是'this.state.data'。如果數據未定義,則錯誤會有所不同。 – vcanales

+0

@devJunk準確地說,讀錯誤加上註釋錯誤行是':-) –

0

ajax調用不會觸發。嘗試爲請求添加方法:GET或POST。