在循环内声明的变量保留了先前的值
Variables declared inside a loop are preserving the prior values
几个小时以来我一直在尝试自己解决这个问题,现在我举手看看是否有人有任何想法。
问题
我正在制作一个动态侧边栏过滤器,它迭代一个 groups
道具和 returns 一个 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>
);
这在我使用 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
点击一个后(比如说第一组——id 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 移出了迭代,但同样的结果。
同样,所有这一切应该做的是根据单击 link.
的结果为导航生成 query.exclude
道具的值
如有任何想法,我们将不胜感激。谢谢。
以下是避免改变 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
基本上遍历数组并检查每个元素。如果 return 值为 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>
我的问题是由于没有完全理解数组的变量赋值。我以为我在复制数组,但我只是在引用它。所以,我实际上是在改变原始值。
我通过更改变量 new_ids
来接收 Array.prototype.slice()
的结果来解决这个问题。
slice
does not alter. It returns a shallow copy of elements from the original array. -MDN
所以我的新行是这样的:
var new_ids = (this.context.router.getCurrentQuery().exclude || []).slice();
几个小时以来我一直在尝试自己解决这个问题,现在我举手看看是否有人有任何想法。
问题
我正在制作一个动态侧边栏过滤器,它迭代一个 groups
道具和 returns 一个 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>
);
这在我使用 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
点击一个后(比如说第一组——id 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 移出了迭代,但同样的结果。
同样,所有这一切应该做的是根据单击 link.
的结果为导航生成query.exclude
道具的值
如有任何想法,我们将不胜感激。谢谢。
以下是避免改变 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
基本上遍历数组并检查每个元素。如果 return 值为 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>
我的问题是由于没有完全理解数组的变量赋值。我以为我在复制数组,但我只是在引用它。所以,我实际上是在改变原始值。
我通过更改变量 new_ids
来接收 Array.prototype.slice()
的结果来解决这个问题。
slice
does not alter. It returns a shallow copy of elements from the original array. -MDN
所以我的新行是这样的:
var new_ids = (this.context.router.getCurrentQuery().exclude || []).slice();