Javascript React:无法访问状态变量的值,数组或迭代器中的每个子级都应具有唯一的;“关键”;道具

Javascript React:无法访问状态变量的值,数组或迭代器中的每个子级都应具有唯一的;“关键”;道具,javascript,reactjs,Javascript,Reactjs,我得到了一个错误:数组或迭代器中的每个子级都应该有一个唯一的“key”属性,如果我在图表提供程序组件中执行console.log(sTime)。它正在向你展示它。我必须在ChartComponent中传递这个值 此图表提供程序组件 var React = require('React'); var ReactDOM = require('ReactDOM'); var Chart = require('react-google-charts').Chart; vat ChartComponent

我得到了一个错误:数组或迭代器中的每个子级都应该有一个唯一的“key”属性,如果我在图表提供程序组件中执行console.log(sTime)。它正在向你展示它。我必须在ChartComponent中传递这个值

此图表提供程序组件

var React = require('React');
var ReactDOM = require('ReactDOM');
var Chart = require('react-google-charts').Chart;
vat ChartComponent = require('ChartComponent');
var ChartConfig = require('ChartConfig');
var date = new Date();

var LineChart = React.createClass({    
     getInitialState: function()
       {
           return ({
              eTime: date.getTime(),
              sTime: this.eTime - (60 * 1000 * range),
          });
      },
      onUpdate: function(){
          var _this = this;
          date = new Date();
          _this.setState({
          eTime: date.getTime(),
          sTime: this.eTime - (60 * 1000 * range)
          })

       },
     render: function () {
         var _this = this;
         var item = [];

     ChartConfig.cList.forEach(function(col, cindex) {
        col.wList.forEach(function(widget, windex) {
           console.log(_this.state.sTime);
           item.push ( <div>
                         <div key={"title_" + cindex + windex} >
                         <div> widget.title </div>
                         </div>
                           <div key={"chart" + cindex + windex} >
                      <ChartComponent width="500px" height="400px"         
                        sTime={_this.state.sTime} 
                        eTime={_this.state.eTime} > 
                   </div>
               </div>
               );          
           });
         });

        return (
               <div >
                    {item}               
               </div>
        )
    }
  });   
  module.exports = LineChart;

我有点担心_this=this的所有重新分配,但那是另一个对话:-)。试着改变这个

  onUpdate: function(){
      var _this = this;
      date = new Date();
      _this.setState({
          eTime: date.getTime(),
          sTime: _this.eTime - (60 * 1000 * range)
      })

   },

另外,请查看“getInitialState”函数。您在的上下文中引用了“this”!这..意思是,这是一个不同的环境。

我有点担心所有的重新分配_this=this,但那是另一个对话:-)。试着改变这个

  onUpdate: function(){
      var _this = this;
      date = new Date();
      _this.setState({
          eTime: date.getTime(),
          sTime: _this.eTime - (60 * 1000 * range)
      })

   },

另外,请查看“getInitialState”函数。您在的上下文中引用了“this”!这..意味着,这是一个不同的环境。

问题似乎在这里:

getInitialState: function() {
   return ({
      eTime: date.getTime(),
      sTime: this.eTime - (60 * 1000 * range),
  });
},
改为:

getInitialState: function() {
   return ({
      eTime: date.getTime(),
      sTime: date.getTime() - (60 * 1000 * range),
  });
},
看起来您试图在一些地方使用
this.eTime
,但它不是组件对象的直接属性,而是组件状态对象的一部分。确保您始终使用
this.state.eTime
,除非您最终使用了
this.eTime=something
,如果它是一个将要更改的值,它应该是状态的一部分

至于keys错误,需要向forEach循环中生成的组件添加键值,如下所示:

col.wList.forEach(function(widget, windex) {
 console.log(_this.state.sTime);
 item.push ( <div key={windex}> // add unique key so react can check diff for performance
               <div key={"title_" + cindex + windex} >
               <div> widget.title </div>
               </div>
                 <div key={"chart" + cindex + windex} >
            <ChartComponent width="500px" height="400px"         
              sTime={_this.state.sTime} 
              eTime={_this.state.eTime} > 
         </div>
     </div>
     );          
 });
});
col.wList.forEach(函数(小部件,windex){
console.log(_this.state.sTime);
item.push(//添加唯一键,以便react可以检查差异的性能
widget.title
);          
});
});


但最基本的是,当您使用迭代器生成JSX时,您应该添加一个唯一的键,这样当react重新启动组件时,它将检查是否有任何更改基于该键。否则,当react重新启动时,没有唯一的键,react将假定它只需要重新启动整个性能较差的东西。

问题似乎在这里:

getInitialState: function() {
   return ({
      eTime: date.getTime(),
      sTime: this.eTime - (60 * 1000 * range),
  });
},
改为:

getInitialState: function() {
   return ({
      eTime: date.getTime(),
      sTime: date.getTime() - (60 * 1000 * range),
  });
},
看起来您试图在一些地方使用
this.eTime
,但它不是组件对象的直接属性,而是组件状态对象的一部分。确保您始终使用
this.state.eTime
,除非您最终使用了
this.eTime=something
,如果它是一个将要更改的值,它应该是状态的一部分

至于keys错误,需要向forEach循环中生成的组件添加键值,如下所示:

col.wList.forEach(function(widget, windex) {
 console.log(_this.state.sTime);
 item.push ( <div key={windex}> // add unique key so react can check diff for performance
               <div key={"title_" + cindex + windex} >
               <div> widget.title </div>
               </div>
                 <div key={"chart" + cindex + windex} >
            <ChartComponent width="500px" height="400px"         
              sTime={_this.state.sTime} 
              eTime={_this.state.eTime} > 
         </div>
     </div>
     );          
 });
});
col.wList.forEach(函数(小部件,windex){
console.log(_this.state.sTime);
item.push(//添加唯一键,以便react可以检查差异的性能
widget.title
);          
});
});


但最基本的是,当您使用迭代器生成JSX时,您应该添加一个唯一的键,这样当react重新启动组件时,它将检查是否有任何更改基于该键。否则,当react重新启动时,没有唯一的键,react将假定它只需要重新启动性能较差的整个事件。

想象一下,在一个循环中,索引变量是:

cindex == 1, windex == 10
// then key is
`title_110`
现在想象一下,在另一个循环中:

cindex == 11, windex == 0
// then key is
key == `title_110`
那是一把重复的钥匙。您应该在某些分隔符之间添加分隔符,例如:

key={"title_" + cindex + "_" + windex}
但是,将数组索引用作组件键并不是一种好的做法。它可能会导致错误(例如,当您洗牌数组时)。您应该使用一些业务标识符

NaN
的问题可能是因为
getInitialState
方法中的
this.eTime
未定义值。以便:

undefined - (60 * 1000 * range) == NaN

假设一个循环中的索引变量是:

cindex == 1, windex == 10
// then key is
`title_110`
现在想象一下,在另一个循环中:

cindex == 11, windex == 0
// then key is
key == `title_110`
那是一把重复的钥匙。您应该在某些分隔符之间添加分隔符,例如:

key={"title_" + cindex + "_" + windex}
但是,将数组索引用作组件键并不是一种好的做法。它可能会导致错误(例如,当您洗牌数组时)。您应该使用一些业务标识符

NaN
的问题可能是因为
getInitialState
方法中的
this.eTime
未定义值。以便:

undefined - (60 * 1000 * range) == NaN

finalfreq是正确的,您没有正确访问state.stime

setstate()仅在经过一小段时间后更新状态,因此在调用setstate后,您无法立即在代码中访问更新的状态。您甚至在完成调用setState之前就尝试访问新状态(同时使用{etime,stime}创建对象)

此外:

在通过ChartConfig.cList.forEach循环后进行渲染

因此,只有在同时呈现所有图表配置时,它们才会更新。我认为每个图表配置上的时间戳都是相同的,因为它们都访问相同的状态。(使用ReactInspector检查此情况)

我建议将它们设置为这样,以获得唯一的密钥:

<ChartComponent width="500px" height="400px"         
    sTime={date.getTime()- (60 * 1000 * range)} 
    eTime={date.getTime()} > 

这可能会为您提供唯一的密钥


另外,还有一点需要注意:尽量使所有内容都处于非状态,除非它必须存在。

finalfreq是正确的,您没有访问state.stime正确

setstate()仅在经过一小段时间后更新状态,因此在调用setstate后无法立即在代码中访问更新的状态。您甚至在完成调用setstate之前就尝试访问新状态(在使用{etime,stime}创建对象时)

此外:

在通过ChartConfig.cList.forEach循环后进行渲染

因此,只有当所有图表配置同时呈现时,它们才会更新。我认为每个图表配置上的时间戳是相同的,因为它们都访问相同的状态。(使用