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

Posted

技术标签:

【中文标题】尝试访问数组后,React 组件返回无法读取 null 的属性 \'__reactInternalInstance$【英文标题】:React component returning cannot read property '__reactInternalInstance$ of null after trying to access array尝试访问数组后,React 组件返回无法读取 null 的属性 '__reactInternalInstance$ 【发布时间】:2016-12-03 20:50:57 【问题描述】:

这是有问题的组件。

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 时,都会收到 Cannot read property '__reactInternalInstance$mincana79xce0t6kk1s5g66r' of 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>
    );
  
); 

【问题讨论】:

这个if (this.props.data !== []) 永远是真的。你可能想试试if (Array.isArray(this.props.data)) ... 或干脆if (this.props.data) ... yup 试过了,还有 vijay 的建议 【参考方案1】:

啊,好吧,这里有一些有趣的问题,但你如此接近。大的,反应你必须总是返回一个***元素(例如一个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 在我运行它时给了我一个“错误的配置”消息,但我关闭了该消息,结果就在那里。不知道那是什么。

【讨论】:

天哪,你是救生员。我刚刚启动程序时遇到了这个错误,现在又出现了。可以肯定地说它现在已经在我的脑海中被锤击了哈哈。我希望我有更多的代表给你,但我失去了我的旧帐户。非常感谢。 我也在拉头发,试图解决这个问题。 React通常能很好地解决它的错误。【参考方案2】:
return (
  theList
)

应该是

return theList

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

return 
  theList: theList

这是 ES6 速记属性语法。

【讨论】:

哈,你知道我看了一眼觉得看起来很有趣 这通常是 JSX 初学者的错误。 :) 根据您的更改编辑问题。虽然仍然收到相同的错误。此时我正在拔头发:( @astringentpattern 对来自 ajax 调用的数据执行 console.log - 如果是 null,那就是这样。 @Jeff ajax 调用按预期返回了一个对象数组【参考方案3】:

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

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

在我的例子中,我试图访问一个在将属性移动到 redux 存储后不存在的状态属性:

// original state
state: 
  files: [],
  user: ,

// ... within render function:
<h1> Welcome this.state.user.username </h1>

我随后将用户移至 redux 存储并从状态中删除了行 // 修改状态 状态: 文件:[], // ... 在渲染函数中(忘记修改):

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

这引发了神秘的错误。通过修改渲染以调用 this.props.user.username,一切都被清除了。

【讨论】:

【参考方案4】:

if语句有个小问题:

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

应该是:

if(this.props.data)

如果 ajax 调用返回 null,则 this.props.data 为 null。或者代码可以更详细。

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

【讨论】:

不幸的是,我对 this.props.data 和 theList 所做的任何类型的检查似乎都没有帮助。出于某种原因,我只是无法返回 theList,即使它已正确填充。 你是对的,我更新了答案。它是 data.constructor === 数组。【参考方案5】:

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

编辑:

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

【讨论】:

你能把console.log返回什么...或者如果它很长的话只是开始和结束。 仅供参考,这将尝试返回一个 array 的 div,这不是 render() 的有效返回值 很好,对不起,我正在复制我使用 的模式,谢谢,我将编辑答案。【参考方案6】:

我在渲染一个无状态组件时遇到了这个错误,并决定在使用基本的 dom 操作渲染它之后删除 react-root-element(包装 div)。

结论:注意这一点,最好不要这样做。

【讨论】:

以上是关于尝试访问数组后,React 组件返回无法读取 null 的属性 '__reactInternalInstance$的主要内容,如果未能解决你的问题,请参考以下文章

如何修复 React 中的“类型错误:尝试访问对象的属性时无法读取未定义的属性名称”

无法读取 React 中未定义的属性“映射”

无法访问 JavaScript 对象数组 (React.js) 中的属性

无法使用React redux读取未定义的地图属性

TypeError:无法读取 React 未定义的属性“标题”

React 15.4.2 无法读取 null 的属性“ref”