Компонент 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, console.log выведет правильный массив объектов, которые мне нужны. Что касается ответов, я попытался вернуть и {theList}, и theList, но это не помогло.

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

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

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>
    );
  }
}); 
 astringentpattern29 июл. 2016 г., 10:51
да попробовал это, а также предложения Виджая
 David Gilbertson29 июл. 2016 г., 10:16
этоif (this.props.data !== []) всегда будет правдой. Вы можете попробоватьif (Array.isArray(this.props.data)) {... или простоif (this.props.data) { ...

Ответы на вопрос(6)

return (
  {theList}
)

должно быть просто

return theList

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

return {
  theList: theList
}

Это синтаксис ES6.

 astringentpattern29 июл. 2016 г., 12:25
@Jeff вызов ajax возвращает массив объектов, как и ожидалось
 Jeff29 июл. 2016 г., 11:39
@astringentpattern делает console.log для данных из вызова ajax - если этоnull тогда это все.
 David Gilbertson29 июл. 2016 г., 11:09
Ха, вы знаете, я посмотрел на это и подумалэто выглядит смешно
 Jeff29 июл. 2016 г., 11:10
Обычно это ошибка новичка с JSX. :)
 David Gilbertson29 июл. 2016 г., 12:38
Ааа, причина этого не работает в том, чтоtheList это массив<div>s. Недопустимое возвращаемое значение дляrender(), Нужен родительский div, смотрите мой ответ ...
 astringentpattern29 июл. 2016 г., 11:30
отредактированный вопрос с вашими изменениями. все еще получаю ту же ошибку, хотя. Я вырываю волосы в этот момент :(

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

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

В моем случае я пытался получить доступ к свойству состояния, которого не было после перемещения свойства в хранилище с избыточностью:

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

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

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

И это бросило загадочную ошибку. Все прояснилось, изменив render для вызова this.props.user.username.

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

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

должно быть:

if(this.props.data){

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

const data = this.props.data;
if(data && data.constructor === Array && data.length > 0) {
 vijayst29 июл. 2016 г., 10:25
Вы правы, я обновил ответ. это data.constructor === Массив.
 astringentpattern29 июл. 2016 г., 10:21
к сожалению, любые проверки, которые я делаю для this.props.data и theList, похоже, не помогают. я просто не могу вернуть {theList} по какой-то причине, хотя он заполняется правильно.

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

Вывод: знай об этом, лучше не делай этого.

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

редактировать:

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>;
    }
  }
});
 astringentpattern29 июл. 2016 г., 10:49
все еще получаю ту же ошибку, к сожалению
 alexi229 июл. 2016 г., 12:38
Хороший улов, извините, я копирую шаблон, где я использую <li> спасибо, я отредактирую ответ.
 alexi229 июл. 2016 г., 10:52
Можете ли вы выложить то, что возвращает console.log ... или просто начало и конец, если он очень длинный.
 David Gilbertson29 июл. 2016 г., 12:37
К вашему сведению это будет попытка вернутьмассив Div, который не является допустимым возвращаемым значением дляrender()
Решение Вопроса

Ах, хорошо, здесь были некоторые интересные проблемы, но вы былитак близко, Большой, с реакцией, вы всегда должны возвращать один элемент верхнего уровня (например, div). Итак, ваша переменнаяtheList был на самом деле массив дивов. Вы не можете вернуть это напрямую. Но вы можете вернуть его, если он заключен в один родительский 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, чтобы после 200 мс возвращать поддельные данные.

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

 David Gilbertson29 июл. 2016 г., 12:46
Я тоже выдергивал свои волосы, пытаясь с этим разобраться. Реагироватьобычно отлично с его ошибками.
 astringentpattern29 июл. 2016 г., 12:42
Боже, ты спасатель. Я сталкивался с этой ошибкой раньше, когда я только запускал программу, и вот она снова. Можно с уверенностью сказать, что это забито в моей голове, ха-ха. Я хотел бы иметь больше представителей, чтобы дать вам, но я потерял свой старый аккаунт. Большое спасибо.

Ваш ответ на вопрос