2015-09-23 10 views
17

Io sto cercando di fare il tutorial: https://facebook.github.io/react/docs/tutorial.htmlCome TypeError: this.props non è definito sulla ReactJs

import React, { PropTypes } from 'react'; 
import classnames from 'classnames'; 
import styles from './CommentBox.css'; 
import withStyles from '../../decorators/withStyles'; 
import Link from '../../utils/Link'; 
import $ from 'jquery'; 

@withStyles(styles) 
class CommentBox extends React.Component { 

    constructor() { 
     super(); 
     this.state = {data: []}; 
    } 

    loadCommentsFromServer() { 
     $.ajax({ 
      url: this.props.url, 
      dataType: 'json', 
      cache: false, 
      success: function(data) { 
       this.setState({data: data}); 
      }.bind(this), 
      error: function(xhr, status, err) { 
       console.error(this.props.url, status, err.toString()); 
      }.bind(this) 
     }) 
    } 

    componentDidMount() { 
     this.loadCommentsFromServer(); 
     setInterval(this.loadCommentsFromServer, this.props.pollInterval); 
    } 

    render() { 

     let url="/public/comments.json" 

     return (
      <div className="commentBox"> 
       <h1>Comments</h1> 
       <CommentList data={this.state.data} /> 
       <CommentForm /> 
      </div> 
     ); 
    } 

} 

class CommentList extends React.Component { 

    render() { 

     let data = this.props.data 

     var commentNodes = data.map(function (comment) { 
      return (
      <Comment author={comment.author}> 
       {comment.text} 
      </Comment> 
     ); 
     }); 

     return (
      <div className="commentList"> 
      {commentNodes} 
      </div> 
     ); 
    } 
}; 

class Comment extends React.Component { 
    render() { 
     return(
      <div className="comment"> 
      <h2 className="commentAuthor"> 
       {this.props.author} 
      </h2> 
      {this.props.children} 
      </div> 
     ); 
    } 
} 

class CommentForm extends React.Component { 
    render() { 
    return (
     <div className="commentForm"> 
     Hello, world! I am a CommentForm. 
     </div> 
    ); 
    } 
}; 

export default CommentBox; 

Tuttavia, il tutorial è un po 'obsolete e sto usando React 0.14-rc1 con la sintassi ES6. Ho fatto del mio meglio per seguire il tutorial e implementarlo nel modo 0.14. È stato in grado di arrivare a questo punto, ma ora ricevendo l'errore:

TypeError: this.props is undefined 

Impossibile risolvere il problema. Qualche idea del perché? Grazie

+1

È possibile fornire la posizione dell'errore nel documento per capire il problema? –

+0

url: this.props.url, – hilarl

+0

Puoi aggiungere questa parte di codice _static defaultProps = { // i tuoi oggetti di scena qui: valore predefinito } _ nella tua classe ComentBox, anche [qui] (http://babeljs.io/blog/2015/06/07/react-on-es6-plus /) un buon esempio di come utilizzare ** React ** e ** ES6 ** –

risposta

32

Quando si utilizza React e ES6 classes React non esegue il binding automatico delle funzioni dichiarate sulla classe.

Pertanto usare sia this.loadCommentsFromServer.bind(this) o utilizzare le funzioni di direzione

loadCommentsFromServer =() => {}

+0

Sembrava che quell'errore andasse via. Ma non riesco ancora a caricare il file Json. Sto ottenendo: un parsererror non definito SyntaxError: JSON.parse: carattere inatteso alla riga 1 colonna 1 dei dati JSON app.js: 34921: 8 loadCommentsFromServer/<. Error <() app.js: 34921 jQuery.Callbacks/fire() app.js: 7771 jQuery.Callbacks/self.fireWith() app.js: 7883 done() app.js: 12938 . invio/callback/<() – hilarl

+1

Il tuo json è malformato. –

+0

Ma ho copiato e incollato i dati JSON nell'esempio del tutorial di reazione. E funziona quando provo a caricarlo dall'interno del componente. Non sto lavorando con il caricamento Ajax. – hilarl

8

Con il passaggio di reagire da createClass a ES6 classes abbiamo bisogno di gestire il valore corretto di this ai nostri metodi per conto nostro, come accennato qui: http://www.newmediacampaigns.com/blog/refactoring-react-components-to-es6-classes modificare il codice per avere il metodo delimitata per correggere il valore di questo nel consructor:

export default class ComponentClass extends React.Component { 
    constructor(props) { 
     super(props); 
     this._myHandler = this._myHandler.bind(this); 
    } 

    _myHandler(props) { 
    console.log(props); 
    } 

    render() { 
    return (
     <div className="col-xs-6 col-md-4"> 
      <button type="button" className="btn btn-danger" onClick={this._myHandler}><i className="fa fa-trash"> Delete</i></button> 
     </div> 
    ) 
    } 
} 

Il no autobinding è stato un passo deliberato dai ragazzi di React per le classi ES6. L'autocreazione per correggere il contesto è stata fornita con React.createClass. I dettagli di questo si possono trovare qui: https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding

Quindi, basato su questo si potrebbe anche modificare il codice come:

export default class ComponentClass extends React.Component { 
    _myHandler = (props) => { 
    console.log(props); 
    } 

    render() { 
    return (
     <div className="col-xs-6 col-md-4"> 
      <button type="button" className="btn btn-danger" onClick={this._myHandler}><i className="fa fa-trash"> Delete</i></button> 
     </div> 
    ) 
    } 
} 
0

Anche se tutte le risposte di cui sopra sono tecnicamente corretta, non ha funzionato nel mio caso. Ho ricevuto qualche pazzo di errore 'proprietà mancanti classe Transform' in modo piuttosto che cercare di capirlo ho definito il gestore nel caso in questo modo:

export class ComponentClass extends React.Component{ 
    _myHandler(event) { 
    event.preventDefault(); 
    console.log(this.props.thingIPassedIn); 
    } 
    render() { 
    return <Button onClick={(event) => this._myHandler(event)} type="button" className="btn btn-danger">Click Me!</Button>; 
    } 
} 

È inoltre possibile passare i parametri in questo modo.

export class ComponentClass extends React.Component{ 
    _myHandler(thingIPassedIn) { 
    console.log(thingIPassedIn); 
    } 
    render() { 
    return <MyOtherComponent defNotAnEvent={(thingIPassedIn) => this._myHandler(thingIPassedIn)} />; 
    } 
} 
Problemi correlati