尝试访问数组后,返回的 React 组件无法读取 null 的属性 '__reactInternalInstance$

IT技术 javascript arrays ajax reactjs react-jsx
2021-04-20 14:38:10

这是有问题的组件。

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错误。但是,如果我用静态 html 替换 {theList},console.log 会打印出我想要的正确对象数组。根据答案,我试图同时返回 {theList} 和 theList 但这没有帮助。

在这两种情况下,console.log 首先打印出 [],我认为这是因为 componentDidMount 包含我从服务器获取 json 的 ajax 调用,并且在第一次 render() 之前还没有触发。我试图检查 this.props.data 是否为空,但它没有帮助。

如果有帮助,这是父组件:

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实际上是一个 div 数组。你不能直接返回那个。但是如果它包含在单个父 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 $奇怪的东西,我只是删除了 jQuery 的 ajax 方法,所以我可以在 200 毫秒后返回一些假数据。

另外,对我来说,jsfiddle 在运行时给了我一个“错误配置”的消息,但我关闭了消息,结果就在那里。不知道那是什么。

天哪,你是救星。我刚启动程序时遇到过这个错误,现在又出现了。可以肯定地说,它现在在我脑海中挥之不去,哈哈。我希望我有更多的代表给你,但我失去了我的旧帐户。非常感谢。
2021-05-29 14:38:10
我也在拉我的头发试图解决这个问题。React通常有很多错误。
2021-06-04 14:38:10
return (
  {theList}
)

应该只是

return theList

因为那时你不在 JSX 中。你在那里做什么将被解释为

return {
  theList: theList
}

这是 ES6 的简写属性语法。

这通常是 JSX 初学者的错误。:)
2021-05-25 14:38:10
哈,你知道我瞥了一眼,觉得这看起来很有趣
2021-05-31 14:38:10
编辑问题与您的更改。仍然收到同样的错误。我现在正在拔头发:(
2021-05-31 14:38:10
@Jeff ajax 调用按预期返回对象数组
2021-06-01 14:38:10
@astringentpattern 对来自 ajax 调用的数据执行 console.log - 如果是null这样,就是这样。
2021-06-20 14:38:10

访问不存在的嵌套状态也可能导致错误:

我缺乏评论的声誉,因此为未来的帮助添加了一个答案——我出于不同的原因遇到了同样的问题。显然,该错误是由较早的错误引发的,该错误抛出了 React 的内部状态,但该错误以某种方式被捕获。github 问题 #8091

就我而言,我试图访问在将属性移动到 redux 存储后不存在的状态属性:

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

我随后将用户移动到 redux 存储并从状态中删除行 // 修改状态 state: { files: [], } // ... 在渲染函数中(忘记修改):

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

这引发了神秘的错误。通过修改渲染来调用 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) {
你是对的,我更新了答案。它是 data.constructor === 数组。
2021-06-14 14:38:10
不幸的是,我对 this.props.data 和 theList 所做的任何类型的检查似乎都没有帮助。我只是因为某种原因无法返回 {theList},即使它被正确填充。
2021-06-21 14:38:10

不确定这是否是您想要的方式,但它对我有用。

编辑:

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>;
    }
  }
});
仅供参考,这将尝试返回一个div数组,它不是一个有效的返回值render()
2021-05-22 14:38:10
很好,抱歉,我正在复制使用 <li> 的模式,谢谢,我将编辑答案。
2021-05-26 14:38:10
你能把 console.log 返回的内容...或者只是开始和结束,如果它很长。
2021-06-15 14:38:10