Возвращающийся компонент React не может прочитать свойство reactInternalInstance$ null после попытки доступа к массиву

вот проблемный компонент, о котором идет речь.

const UserList = React.createClass({
  render: function(){
    let theList;
    if(this.props.data){
      theList=this.props.data.map(function(user, pos){
        return (
          <div className="row user">
            <div className="col-xs-1">{pos}</div>
            <div className="col-xs-5">{user.username}</div>
            <div className="col-xs-3">{user.recent}</div>
            <div className="col-xs-3">{user.alltime}</div>
          </div>
        );
      }, this);
    } else {
     theList = <div>I don't know anymore</div>;
    }
    console.log(theList);
    return (
      theList
    );
  }
});

всякий раз, когда я пытаюсь вернуть {theList}, я получаю не удается прочитать свойство '_ _ reactInternalInstance$mincana79xce0t6kk1s5g66r ' из null ошибка. Однако, если я заменю {theList} на статический html, консоль.журнал печатает правильный массив объектов, которые я хочу. Согласно ответам, я попытался вернуть как {theList}, так и theList, но это не помогло.

в обоих случаях консоль.log first распечатывает [], который я предполагаю, потому что componentDidMount содержит мой вызов ajax для получения json с сервера и еще не запущен до первого render(). Я пытался проверить против этот.реквизит.данные являются нулевыми, но это не помогает.

вот родительский компонент, если он помогает:

const Leaderboard = React.createClass({
  getInitialState: function(){
    return ({data: [], mode: 0});
  },
  componentDidMount: function(){
    $.ajax({
      url: 'https://someurlthatreturnsjson',
      dataType: 'json',
      cache: false,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error('https://someurlthatreturnsjson', status, err.toString());
      }.bind(this)
    });
  },
  render: function(){
    return (
      <div className="leaderboard">
        <div className="row titleBar">
          <img src="http://someimage.jpg"></img>Leaderboard
        </div> 
        <HeaderBar />
        <UserList data={this.state.data}/>
      </div>
    );
  }
}); 

6 ответов


Ах хорошо, здесь были некоторые интересные проблемы, но вы были так близко. Большой, с react вы всегда должны возвращать один элемент верхнего уровня (например, div). Итак, ваша переменная theList на самом деле был массив divs. Вы не можете вернуть это напрямую. Но вы можете вернуть его, если он завернут в один родительский div.

const mockData = [
	{
  	username: 'bob',
    recent: 'seven',
    alltime: 123,
  },
	{
  	username: 'sally mae',
    recent: 'seven',
    alltime: 133999,
  },
];

var $ = {
	ajax(opt) {
  	setTimeout(() => {
    	opt.success(mockData);
    }, 200);
  }
}

const UserList = React.createClass({
  render: function(){
  	let theList;
    if (this.props.data && this.props.data.length) {
      theList = this.props.data.map(function(user, pos){
        return (
          <div key={user.username} className="row user">
            <div className="col">{pos}</div>
            <div className="col">{user.username}</div>
            <div className="col">{user.recent}</div>
            <div className="col">{user.alltime}</div>
          </div>
        );
      });
    } else {
      theList = <div>There is NO data</div>;
    }
    
    return <div>{theList}</div>;
  }
});

const Leaderboard = React.createClass({
  getInitialState: function(){
    return ({data: [], mode: 0});
  },
  componentDidMount: function(){
    $.ajax({
      url: 'https://someurlthatreturnsjson',
      dataType: 'json',
      cache: false,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error('https://someurlthatreturnsjson', status, err.toString());
      }.bind(this)
    });
  },
  render: function(){
    return (
      <div className="leaderboard">
        <UserList data={this.state.data}/>
      </div>
    );
  }
}); 

ReactDOM.render(
  <Leaderboard/>,
  document.getElementById('container')
);
.col {
  width: 200px;
  float: left;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js"></script>

<div id="container">
  <!-- This element's contents will be replaced with your component. -->
</div>

чтобы немного объяснить скрипку. Не беспокойтесь о странном взгляде var $ материал, я просто тушу метод ajax jQuery, чтобы я мог вернуть некоторые поддельные данные после 200ms.

кроме того, для меня jsfiddle дает мне сообщение "плохой конфигурации", когда я его запускаю, но я закрываю сообщение, и результат есть. Не знаю, что это.


return (
  {theList}
)

должна быть

return theList

потому что вы не внутри JSX в этот момент. То, что вы там делаете, будет интерпретироваться как

return {
  theList: theList
}

это синтаксис свойств стенографии ES6.


ошибка также может возникнуть при доступе к вложенному состоянию, которое не существует:

мне не хватает репутации для комментариев, поэтому, добавив ответ для будущей помощи, я столкнулся с этой же проблемой по другой причине. По-видимому, ошибка запускается из более ранней ошибки, сбрасывающей внутреннее состояние react, но ошибка каким-то образом ловится. выпуск github #8091

в моем случае я пытался получить доступ к свойству состояния, которое не существовало после перемещения свойство redux store:

// original state
state: {
  files: [],
  user: {},
}
// ... within render function:
<h1> Welcome {this.state.user.username} </h1>

впоследствии я переместил пользователя в хранилище redux и удалил строку из состояния // измененное состояние государство: { файлы: [], } // ... внутри функции рендеринга (забыл изменить):

<h1> Welcome {this.state.user.username} </h1>

и это вызвало загадочную ошибку. Все было очищено путем изменения render для вызова этого.реквизит.пользователь.имя пользователя:.


существует небольшая проблема с оператором if:

if(this.props.data !== []){

должно быть:

if(this.props.data){

этого.реквизит.данные имеют значение null, если вызов ajax возвращает значение null. в качестве альтернативы кодекс мог бы быть более сложным.

const data = this.props.data;
if(data && data.constructor === Array && data.length > 0) {

Не уверен, что это так, как вы хотите это сделать, но это работает для меня.

edit:

const UserList = React.createClass({
  render: function() {
    if(this.props.data){
      return this.props.data.map(function(user, pos){
        return (
          <li> className="row user">
            <span>{pos}</span>
            <span>{user.username}</span>
            <span>{user.recent}</span>
            <span>{user.alltime}</span>
          </li>
        );
      });
    } else {
      return <li>I don't know anymore</li>;
    }
  }
});

Я столкнулся с этой ошибкой, когда я визуализировал компонент без состояния и решил удалить элемент react-root (wrapping div) после рендеринга его с базовой манипуляцией dom.

заключение: знайте об этом, лучше не делайте этого.