2014-10-16 59 views
35

讓我先說這個,說我是ReactJS的新手。我試圖通過使用React填充數據的簡單網站來學習。我有一個JSON文件,其中包含將通過地圖循環的鏈接數據。ReactJS this.state null

我試圖將其設置爲組件的狀態,然後通過一個道具將它傳遞給導航欄鏈接,但我得到「遺漏的類型錯誤:無法讀取屬性空的‘數據’」

我試着到處尋找解決方案,但找不到任何東西。

注意:當我嘗試硬編碼一個對象並通過它映射它時,它返回的地圖是未定義的。但是我不確定這是否與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

你拼寫錯了'getInitialState'(你剛剛在t之後錯過'i') – trekforever 2014-10-16 17:31:16

+2

看起來像@trekforever發現你的問題。至於說,你的'console.log(this.state.data)'可能不會輸出正確的結果,因爲React會對'setState'調用進行排隊。如果你想在調用'setState'後打印你的狀態,你必須提供一個回調函數: 'this.setState({something:'blah'},function(){console.log(this.state.something); });' – edoloughlin 2014-10-16 22:02:40

+0

@trekforever DERP,謝謝! – 2014-10-17 15:53:41

回答

8

this.state.data爲null,在你的例子,因爲setState()是異步。相反,你可以傳遞一個回調SETSTATE像這樣:

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

使用ES6,初始狀態必須在構造函數中創建的陣營組件類,像這樣:

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

this documentation

+1

這個可以幫助我。 構造(道具:任何) { 超(道具) this.state = { 模型:新RegistrationModel() } 和NOT this.setState } 感謝 – 2016-04-13 15:48:26

+0

WAW,好工作的朋友 – yussan 2017-03-23 09:02:40

6

更實際的答案,使用ES7 +類:

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

ES6類(alredy得到的回答)

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

這個問題已經回答了,但我來到這裏具有一個問題,很容易發生在任何人身上。

我得到一個console.log(this.state)在我的方法之一登錄null,只是因爲我還沒有寫道:

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

在我的構造函數。

因此,如果您在其中一個方法中獲得null for this.state,請檢查是否已將其綁定到您的組件。

乾杯!

編輯(因爲@ tutiplain的問題)

爲什麼我越來越nullthis.state

因爲我寫了console.log(this.state)在我的類沒有約束的方法(我的handleSelect方法)。這導致this指向對象層次結構中較高的某個對象(最有可能是window對象),該對象沒有名爲state的屬性。因此,通過將我的handleSelect方法綁定到this,我確信,只要我在該方法中編寫this,它就會指向該方法所在的對象。

我鼓勵您閱讀關於此here的非常好的解釋。

+0

這一個實際上幫助了我。那裏有很多過時的教程。但我不明白它爲什麼起作用。如果我在同一個班級,是不是該班級所有方法之間共享的狀態對象?爲什麼我必須手動將「this」綁定到該方法? – tutiplain 2017-12-29 19:56:07

+0

我編輯了我的評論和簡短的解釋。請務必查看我最後留下的鏈接。 :) – 2017-12-30 18:11:17