Подтвердить что ты не робот

ReactJS this.state null

Позвольте мне предисловие к этому, сказав, что я новичок в ReactJS. Я пытаюсь учиться, создавая простой сайт, который заполняет данные с помощью React. У меня есть файл JSON, содержащий данные о ссылках, которые будут зацикливаться на карте.

Я попробовал установить его как состояние компонентов, а затем передать его в ссылки на навигацию через prop, но я получаю "Uncaught TypeError: не могу прочитать данные свойства" null "

Я пытался осматривать решения, но ничего не мог найти.

Примечание. Когда я пытаюсь жестко закодировать объект и отображать его таким образом, он возвращает карту undefined. Однако я не уверен, что это напрямую связано с ошибкой 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')
);
4b9b3361

Ответ 1

Используя ES6, исходное состояние должно быть создано в вашем конструкторе для класса компонентов React, например:

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

Смотрите эту документацию.

Ответ 2

this.state.data является нулевым в вашем примере, потому что 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

Ответ 3

Более реальный ответ для использования классов ES7 +:

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

Классы ES6 (ответил alredy)

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

Ответ 4

Этот вопрос уже был дан ответ, но я пришел сюда, столкнувшись с проблемой, которая может легко случиться с кем-либо.

Я получал console.log(this.state) для регистрации null в одном из моих методов, просто потому, что я не писал:

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

в моем конструкторе.

Итак, если вы получаете null для this.state в одном из своих методов, убедитесь, что вы привязываете его к своему компоненту.

Ура!

Изменить (из-за вопроса @tutiplain)

Почему я получил null для this.state?

Потому что я написал console.log(this.state) в методе, который не был ограничен моим классом (мой метод handleSelect). Это заставило this указать на какой-то объект выше в иерархии объектов (скорее всего это объект window), который не имеет свойства с именем state. Поэтому, привязывая мой метод handleSelect к this, я заверил, что всякий раз, когда я пишу this в этом методе, он укажет на объект, в котором находится этот метод.

Я рекомендую вам прочитать действительно хорошее объяснение этого здесь.