web-dev-qa-db-fra.com

Le composant React renvoyé ne peut pas lire la propriété '__reactInternalInstance $ of null après une tentative d'accès au tableau

Voici le composant problématique en question. 

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
    );
  }
});

Chaque fois que j'essaie de renvoyer {theList}, je reçois un Impossible de lire la propriété '__reactInternalInstance $ mincana79xce0t6kk1s5g66r' de null error. Cependant, si je remplace {theList} par du code HTML statique, console.log affiche le tableau d'objets correct que je souhaite. D'après les réponses, j'ai essayé de retourner {theList} et theList mais cela n'a pas aidé.

Dans les deux cas, console.log affiche d'abord [], ce qui, je suppose, est dû au fait que composantDidMount contient mon appel ajax pour obtenir JSON du serveur et ne s'est pas encore déclenché avant le premier render (). J'ai essayé de vérifier contre This.props.data étant null mais cela n'aide pas.

Voici le composant parent si cela peut aider: 

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>
    );
  }
}); 
8
astringentpattern

Ah, d'accord, il y avait quelques problèmes intéressants ici, mais vous étiez si proche . Le grand, avec react, vous devez toujours renvoyer un seul élément de premier niveau (par exemple, un div). Ainsi, votre variable theList était en réalité un tableau de divs. Vous ne pouvez pas retourner cela directement. Mais vous pouvez le retourner s'il est enveloppé dans une div parent unique.

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>

Pour expliquer le violon un peu. Ne vous inquiétez pas pour les trucs bizarres de var $, je ne fais que masquer la méthode ajax de jQuery pour pouvoir renvoyer de fausses données après 200 ms.

De plus, jsfiddle me donne un message de "mauvaise configuration" lorsque je l'exécute, mais je ferme le message et le résultat est là. Je ne sais pas ce que c'est.

8
David Gilbertson
return (
  {theList}
)

devrait juste être

return theList

parce que vous n'êtes pas à l'intérieur de JSX à ce stade. Ce que vous faites là sera interprété comme

return {
  theList: theList
}

C'est la syntaxe des propriétés abrégées de ES6.

4
Jeff

Une erreur peut également provenir d'un accès à un état imbriqué inexistant:

Je n'ai pas la réputation de commenter, alors j'ajoute une réponse pour une assistance future - je rencontre ce même problème pour une raison différente. Apparemment, l’erreur est provoquée par une erreur précédente qui jette l’état interne de Rea, mais elle est en quelque sorte interceptée. Numéro github n ° 8091

Dans mon cas, j'essayais d'accéder à une propriété d'état qui n'existait pas après avoir déplacé la propriété vers le magasin redux:

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

J'ai par la suite déplacé l'utilisateur vers le magasin redux et la ligne supprimée de l'état // état modifié Etat: { des dossiers: [], } // ... dans la fonction de rendu (oublié de modifier):

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

Et cela a jeté l'erreur cryptique. Tout a été éclairci en modifiant le rendu pour appeler sur this.props.user.username. 

1
Reid Henderson

J'ai rencontré cette erreur lorsque j'ai rendu un composant sans état et j'ai décidé de supprimer l'élément rea-root (wrapping div) après l'avoir rendu avec une manipulation de base du dom.

Conclusion: soyez conscient de cela, mieux vaut ne pas le faire.

0
ant45de

Il y a un petit problème avec l'énoncé if:

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

devrait être:

if(this.props.data){

this.props.data est null, si l'appel ajax renvoie null. sinon, le code pourrait être plus élaboré.

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

Je ne sais pas si c'est ce que vous voulez faire, mais cela fonctionne pour moi.

modifier:

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>;
    }
  }
});
0
alexi2