2014-10-16 10 views
35

Lasciatemi prefigurare ciò dicendo che sono un principiante di ReactJS. Sto cercando di imparare creando un sito semplice che popola i dati usando React. Ho un file JSON che contiene dati di collegamento che verranno collegati in loop con la mappa.ReactJS this.state null

ho provato a fissare come lo stato dei componenti poi passarlo ai collegamenti della barra di navigazione tramite un oggetto di scena ma sto ricevendo "TypeError Uncaught: Impossibile leggere la proprietà 'dati' di null"

Ho provato a cercare in giro per il soluzioni ma non riusciva a trovare nulla.

Nota: quando provo a codificare un oggetto e a mapparlo in questo modo, restituisce una mappa non definita. Tuttavia non sono sicuro che sia direttamente correlato all'errore setState.

/** @jsx React.DOM */ 

var conf = { 
    companyName: "Slant Hosting" 
    }; 

var NavbarLinks = React.createClass({ 
    render: function(){ 
    var navLinks = this.props.data.map(function(link){ 
     return(
     <li><a href={link.target}>{link.text}</a></li> 
    ); 
    }); 
    return(
     <ul className="nav navbar-nav"> 
     {navLinks} 
     </ul> 
    ) 
    } 
}); 

var NavbarBrand = React.createClass({ 
    render: function(){ 
    return(
     <a className="navbar-brand" href="#">{conf.companyName}</a> 
    ); 
    } 
}); 

var Navbar = React.createClass({ 
    getInitalState: function(){ 
    return{ 
     data : [] 
    }; 
    }, 
    loadNavbarJSON: function() { 
    $.ajax({ 
     url: "app/js/configs/navbar.json", 
     dataType: 'json', 
     success: function(data) { 
     this.setState({ 
      data: data 
     }); 
     console.log(data); 
     console.log(this.state.data); 
     }.bind(this), 
     error: function(xhr, status, err) { 
     console.error(this.props.url, status, err.toString()); 
     }.bind(this) 
    }); 
    }, 
    componentDidMount: function(){ 
    this.loadNavbarJSON(); 
    }, 
    render: function(){ 
    return(
     <nav className="navbar navbar-default navbar-fixed-top" role="navigation"> 
     <div className="container-fluid"> 
      <div className="navbar-header"> 
      <NavbarBrand /> 
      </div> 
      <NavbarLinks data={this.state.data} /> 
     </div> 
     </nav> 
    ); 
    } 
}); 

var Header = React.createClass({ 
    render: function(){ 
    return(
     <Navbar /> 
    ); 
    } 
}); 

React.renderComponent(
    <Header />, 
    document.getElementById('render') 
); 
+22

hai sbagliato a digitare 'getInitialState' (ti manca l''i' subito dopo la t in iniziale) – trekforever

+2

Sembra che @trekforever abbia trovato il tuo problema. Come a parte, 'console.log (this.state.data)' probabilmente non stamperà i risultati corretti, poiché React accoderà la chiamata 'setState'. Se vuoi stampare il tuo stato dopo una chiamata a 'setState' devi fornire un callback: ' this.setState ({something: 'blah'}, function() {console.log (this.state.something); }); ' – edoloughlin

+0

@trekforever DERP, grazie! –

risposta

8

this.state.data è nullo nel tuo esempio perché setState() è asincrona. Invece è possibile passare un callback per setstate in questo modo:

loadNavbarJSON: function() { 
    $.ajax({ 
     url: "app/js/configs/navbar.json", 
     dataType: 'json', 
     success: function(data) { 
     console.log(data); 

     this.setState({data: data}, function(){ 
      console.log(this.state.data); 
     }.bind(this)); 

     }.bind(this), 
    }); 
    } 

https://facebook.github.io/react/docs/component-api.html#setstate

35

Utilizzando ES6, lo stato iniziale deve essere creato nel costruttore per la classe componente Reagire, in questo modo:

constructor(props) { 
    super(props) 
    this.state ={ 
    // Set your state here 
    } 
} 

Vedere this documentation.

+1

Questo mi aiuta. costruttore (oggetti di scena: eventuali) { super (oggetti di scena) this.state = { modello New RegistrationModel()} e NON this.setState } Grazie –

+0

waw, buoni amici di lavoro – yussan

6

Più risposta effettiva, per l'utilizzo di ES7 + Classi:

export class Counter extends React.Component { 
    state = { data : [] }; 
    ... 
} 

ES6 Classes (giá stato risposto)

export class Component extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { data : [] }; 
    } 
    ... 
} 
3

Questa domanda è già stato risposto, ma sono venuto qui per avere un problema che può facilmente capitare a chiunque.

mi è stato sempre un console.log(this.state) per accedere null in uno dei miei metodi, solo perché non ho scritto:

this.handleSelect = this.handleSelect.bind(this);

nel mio costruttore.

Quindi, se stai ricevendo uno null per questo.stato in uno dei tuoi metodi, controlla di averlo associato al componente.

Cheers!

Modifica (a causa della domanda di @ tutiplain)

Perché ero ottenendo null per this.state?

Perché ho scritto console.log(this.state) nel metodo che non era limitato alla mia classe (il mio metodo handleSelect). Ciò ha causato this in modo che punti a un oggetto più in alto nella gerarchia dell'oggetto (molto probabilmente l'oggetto window) che non ha una proprietà denominata state. Quindi, legando il mio metodo handleSelect a this, ho assicurato che ogni volta che scrivo this in quel metodo, punterà all'oggetto in cui si trova il metodo.

Vi incoraggio a leggere una spiegazione molto buona per questo here.

+0

Questo in realtà mi ha aiutato. Un sacco di tutorial obsoleti là fuori. Ma non capisco perché funzioni. Se sono nella stessa classe, non è l'oggetto stato condiviso tra tutti i metodi di quella classe? Perché devo legare manualmente "questo" al metodo? – tutiplain

+0

Ho modificato il mio commento con una breve spiegazione. Assicurati di controllare il link che ho lasciato alla fine. :) –