我最近开始使用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
的来源,我不能肯定地说这是正确的。但是我以前见过这种行为,这就是原因。关于javascript - ReactJS-状态变量行为异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60011129/