web-dev-qa-db-ja.com

ReactJS this.state null

私がReactJSの初心者であると言って、これを序文させてください。 Reactを使用してデータを入力する簡単なサイトを作成して、学習しようとしています。マップでループスルーされるリンクデータを含むJSONファイルがあります。

私はそれをコンポーネントの状態として設定してから、小道具を介してnavbarリンクに渡しましたが、「Uncaught TypeError:Cannot read property 'data' of null」を取得しています

解決策を探してみましたが、何も見つかりませんでした。

注:オブジェクトをハードコーディングし、マップを返す方法でオブジェクトをマップしようとすると、mapは未定義になります。ただし、それが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')
);
53

ES6を使用して、次のようにReactコンポーネントクラスのコンストラクターで初期状態を作成する必要があります。

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

このドキュメント を参照してください。

59
yussan

この質問はすでに答えられていますが、私は誰にでも簡単に起こりうる問題を抱えてここに来ました。

私が書いていないという理由だけで、私のメソッドの1つでnullを記録するconsole.log(this.state)を取得していました:

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

私のコンストラクタで。

したがって、いずれかのメソッドでthis.stateのnullを取得している場合は、コンポーネントにバインドしているかどうかを確認してください。

乾杯!

Edit(@tutiplainの質問のため)

_this.state_でnullを取得したのはなぜですか?

クラスにバインドされていないメソッド(handleSelectメソッド)でconsole.log(this.state)を作成したためです。そのため、thisは、windowという名前のプロパティを持たないオブジェクト階層の上位のオブジェクト(ほとんどの場合、stateオブジェクト)を指します。したがって、私のhandleSelectメソッドをthisにバインドすることにより、そのメソッドでthisを記述するたびに、メソッドが含まれるオブジェクトを指すようになりました。

これについて本当に良い説明を読むことをお勧めします here

11
Filip Savic

setState()は非同期であるため、この例ではthis.state.dataはnullです。代わりに、次のようにコールバックを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

10
Blair Anderson

ES7 +クラスを使用するためのより実際の答え:

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

ES6クラス(すでに回答済み)

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

同様の問題がありました。私の場合、webpack-dev-server実行中に自分のものを適切に再コンパイルしません。

開発サーバーを再起動して、再び機能するようにしました。
このようなことが起こることを心に留めておく価値があると思います。

0
Grigory Bogush