在循环内声明的变量保留先前值

时间:2015-08-26 15:33:58

标签: javascript reactjs react-router

我一直在努力解决这个问题几个小时,现在我举起手来看看是否有人有任何想法。

问题

我正在创建一个动态侧边栏过滤器,它会迭代groups道具并返回带有查询道具的Link来更新路由器。系统会显示一个复选框,并根据当前是否排除该组ID进行标记。

守则



render: function() {
  return (
    <ul>
    {this.props.query.filter == 'connections' ?
     // the array of groups to build the filter for
     this.props.groups.map(function (group) {
     // this array would start with the currently excluded ids, and end with the new list of ids
     var new_ids = this.context.router.getCurrentQuery().exclude || [];
     var index = new_ids.indexOf(group.id.toString());
     console.log('my id: ' + group.id);
     console.log('starting: ' + new_ids);
     // again, the array is excluded ids, so if it's not in the array it should be checked
     var selected = index == -1;
     if (selected) {
       // if this link is clicked, add the id to the excludes
       new_ids.push(group.id);
     }
     else {
       // if this linked is clicked, remove the id from the excludes
       new_ids.splice(index, 1);
     }
     console.log('ending: '+new_ids);
     // return the preloaded link
     return <Link  key={group.name}
                   to="feed"
                   query={{filter: 'connections', exclude: new_ids}}>
              <small>{group.name}</small>
            </Link>;
      }, this) : null }
   </ul>
);
&#13;
&#13;
&#13;

当我使用input type="checkbox"和使用this.transitionTo的事件处理程序时,这有效,但我想使用Link组件来处理请求而不是事件处理程序。

结果

页面在第一次单击(query.exclude == undefined)时工作正常,但在此之后new_ids每次迭代都会发生变化。 这是控制台输出...

id: 11
starting: 
new ids: 11
id: 6
starting: 
new ids: 6
id: 21
starting: 
new ids: 21

点击一个(比如说第一组 - 身份11,它搞砸了)......

id: 11
starting: 11
new ids: // this is correct, it removes 11 from the list
id: 6
starting: // this should be 11, instead its inheriting the prior value
new ids: 6 // this should be 11, 6
id: 21
starting: 6 // this should be 11, instead its inheriting the prior value
new ids: 6,21 // this should be 11, 21

我已尝试将此次迭代设为for ... loop而不是.map(),但这并没有帮助。我还将初始的excluded_ids移出了迭代,但同样的结果。

同样,所有这一切应该是根据点击链接的结果为导航生成query.exclude道具的值。

任何有关可能出现的想法都将受到赞赏。谢谢。

2 个答案:

答案 0 :(得分:1)

以下是您可以避免改变exclude数组的方法。

render: function() {
  return (
    <ul>
    {this.props.query.filter == 'connections' ?
     // the array of groups to build the filter for
     this.props.groups.map(function (group) {
     // this array would start with the currently excluded ids, and end with the new list of ids
     var new_ids = this.context.router.getCurrentQuery().exclude || [];
     console.log('my id: ' + group.id);
     console.log('starting: ' + new_ids);
     
     var found = false;
     new_ids = new_ids.filter(function(exclude){
         if(exclude != group.id.toString()){
            return true;
         } else {
            found = true;
            return false;
         }
     });

     if(!found) {
        new_ids.push(group.id);
     } 
     //new_ids now has a copy of the exclude array with the values excluded.

     console.log('ending: '+new_ids);
     // return the preloaded link
     return <Link  key={group.name}
                   to="feed"
                   query={{filter: 'connections', exclude: new_ids}}>
              <small>{group.name}</small>
            </Link>;
      }, this) : null }
   </ul>
);

Array.prototype.filter基本上遍历数组并检查每个元素。如果返回值为true,则会将其添加到新数组中,否则将丢弃正在迭代的元素。

这是一个以类似方式工作的非反应脚本。

var group = [1,2,3,4,5,6,7,8,9,10,11];
var excluded = [11];
var results = document.getElementById('results');

group.forEach(function(group){
    var new_ids = excluded;
    results.innerHTML += 'my id: ' + group + '\n';
    results.innerHTML += 'starting: ' + new_ids + '\n';
  
    var found = false;
    new_ids = new_ids.filter(function(exclude){
       if(exclude != group){
           return true;
       } else {
           found = true;
           return false;
       }
    });
     
    if(!found){
        new_ids.push(group);
    }
    results.innerHTML += 'ending: ' + new_ids + '\n';
});
<pre id="results"></pre>

答案 1 :(得分:0)

我的问题是由于没有完全理解对数组的变量赋值。我以为我在复制数组,但我只是在引用它。所以,我实际上是在改变原来的价值。

我通过更改变量var prizesList : [PrizeItem] = [] 来修复此问题,以便接收new_ids的结果。

  

Array.prototype.slice()不会改变。它返回原始数组中元素的浅表副本。 - MDN

所以我的新行看起来像这样:

slice