javascript - ReactJS - 状态变量行为异常
问题描述
我最近开始使用 React,遇到了一个看似与状态变量相关的问题。
bSort(){
this.setState(
state => {
console.log("PRE BSORT STATE", state)
let current_members = [...state.members];
console.log("members pre BSORT", current_members);
const updated_states = bubbleSort([...current_members]);
return {states: updated_states, animate : true};
},
() => this.animate()
);
}
在这里,我尝试使用从函数 bubbleSort 返回的信息来更新我的状态。问题是bubbleSort的结果很奇怪:我期待一个数组数组,其中每个单独的数组代表排序进行时列表的快照。理想情况下,我会将这些快照中的每一个用作动画的帧,但实际上返回的数组由排序的最终结果的多个副本组成。这很奇怪,特别是因为我在排序过程中明确尝试保存原始步骤和中间步骤。请参阅底部的 bubbleSort() 代码。
我知道这里有很多文字,但我非常感谢帮助理解正在发生的事情,我不知所措。谢谢!
编辑:
我正在添加 bubbleSort() 的代码,以便提供更多信息。
export default function bubbleSort(list){
let members = [...list];
let frames= [];
//the original order of the members should be the first frame in the list
frames.push(members);
let early_exit = false;
let wall = members.length;
while(!early_exit){
console.log("FRAMES WITHIN BSORT", frames);
let last_change_index = null;
for(var i = 0; i < wall; i++){
if(members[i+1] != null){
console.log("COMPARING", members[i].props.style.height, "AND", members[i+1].props.style.height);
//Here we color red the two elements that will be compared
var new_1 = React.cloneElement(
members[i],
{
style : {backgroundColor : "red", height : members[i].props.style.height}
}
);
var new_2 = React.cloneElement(
members[i+1],
{
style : {backgroundColor : "red", height : members[i+1].props.style.height}
}
);
members[i] = new_1;
members[i+1] = new_2;
//and add this new comparison state to the list of frames
frames.push(members);
//now we decide if we need to swap the elements
if(members[i].props.style.height > members[i+1].props.style.height){
console.log("SWAPPING", i, i+1);
//If should swap, the two elements are colored yellow and shifted on the x axis
let new_1_yellow = React.cloneElement(
new_1,
{
animate : {x : 3},
style : {backgroundColor : "yellow", height : new_1.props.style.height}
}
);
let new_2_yellow = React.cloneElement(
new_2,
{
animate : {x : -3},
style : {backgroundColor : "yellow", height : new_2.props.style.height}
}
);
members[i+1] = new_1_yellow;
members[i] = new_2_yellow;
last_change_index = i;
frames.push(members);
//We change the yellow swapped members back to blue
let new_1_blue = React.cloneElement(
new_1_yellow,
{
animate : {x : 0},
style : {backgroundColor : "blue", height : new_1_yellow.props.style.height}
}
);
let new_2_blue = React.cloneElement(
new_2_yellow,
{
animate : {x : 0},
style : {backgroundColor : "blue", height : new_2_yellow.props.style.height}
}
);
members[i+1] = new_1_blue;
members[i] = new_2_blue;
//and add this return to blue state to the list
frames.push(members);
}
else{
//Here we re-color blue the two elements that were compared
let new_1_blue = React.cloneElement(
new_1,
{
style : {backgroundColor : "blue", height : new_1.props.style.height}
}
);
let new_2_blue = React.cloneElement(
new_2,
{
style : {backgroundColor : "blue", height : new_2.props.style.height}
}
);
members[i] = new_1_blue;
members[i+1] = new_2_blue;
//and add this return to blue state to the list
frames.push(members);
}
}
}
if(last_change_index == null){
early_exit = true;
}
wall = last_change_index;
}
return frames;
}
解决方案
我认为它的工作方式与您期望的一样,但是控制台会在更改后检查该值。
如果bubbleSort()
在适当的位置改变您的数据,而不是返回一个新的原始副本并进行编辑,那么您的控制台只是保留一个对象引用,然后在您检查它时显示它的当前值。
这是您希望不可变地对待状态的原因之一,还有许多其他原因。永远不要改变状态中的对象。始终提供状态中的新对象。
我打赌这会解决你的问题:
bubbleSort([...members]);
但是您可能应该实现冒泡排序以返回一个新的数组或对象,而不是修改现有的。
没有来源bubbleSort
我不能肯定这是正确的。但我以前见过这种行为,这就是原因。
推荐阅读
- python - 为什么以下目录搜索会导致无限循环?
- python - 反向传播实现
- python - 计算每个单词出现的行数
- ios - 将 Xamarin.ios .IPA 部署到目标 iOS 设备(即 iPhone)的步骤是什么?
- python - Azure Key Vault 是否支持客户端证书?
- c - fgets返回null后有没有办法回到while循环?
- python - pandas 使用 apply 方法并发送列名?
- salesforce - 如何获取类似于 Sonarqube 的 Salesforce 代码覆盖率报告
- php - 在 PHP 中处理来自 ajax 的序列化数组
- sql - 计算每年的客户数量(新客户和回头客)