2016-05-31 14 views
0

Ich versuche, eine Komponente zu implementieren, die Ajax-Anforderungen an den Server verarbeitet und Daten an zwei untergeordnete Komponenten übergibt. Wie auch immer, es scheint, dass die Ajax-Aufrufe nie gemacht werden.React-Komponente nicht Ajax Anruf

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

ist der Fehler, den ich bekomme.

// 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> 
       ) 
     } 
    } 

EDIT:

Hier ist der Code für die Futtermittelkomponente, einer der beiden untergeordneten Komponenten von Frontpage, die Requisiten aus seinem übergeordneten

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)' sieht falsch aus. Welches ist die Zeile des Fehlers? –

+0

Anfangs ist Ihr 'this.state.data' ein leeres Array, aber Sie versuchen,' this.state.data.feedData' in der 'render'-Funktion aufzurufen, was bedeutet, dass Sie erwarten, dass es ein Objekt ist. Vielleicht sollte die staatliche Struktur klarer und konsequenter werden. – Kujira

+0

@Kujira danke Das habe ich nicht bemerkt, vorher habe ich ein Array zurückgegeben und jetzt ist es tatsächlich ein Objekt. Ich änderte es in Daten = {}, aber ich bekomme den gleichen Fehler –

Antwort

2

Sie müssen übergeben wird, um Definieren Sie das Ausgangszustandsobjekt in ThreadsBox, so ist es nicht null:

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

Durch Lesen des Fehlers können Sie diese Schlussfolgerung ziehen. 'Kann Eigenschaft 'Daten' von Null nicht lesen 'bedeutet, dass was auch immer vor' Daten 'ist, was nicht existiert, sei' this.props.data' oder' this.state.data'. Wenn Daten nicht definiert waren, würde der Fehler anders sein. – vcanales

+0

@devJunk genau, Lesen des Fehlers plus der Kommentar, dass die Fehlerzeile '' :-) –

0

Der Ajax-Aufruf wird nicht ausgelöst. Versuchen Sie, die Methode für die Anforderung hinzuzufügen: GET oder POST.