2014-10-16 28 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