Javascript ReactJS-状态变量的行为异常
我最近开始使用React,遇到了一个似乎与状态变量有关的问题Javascript ReactJS-状态变量的行为异常,javascript,reactjs,state,Javascript,Reactjs,State,我最近开始使用React,遇到了一个似乎与状态变量有关的问题 bSort(){ this.setState( state => { console.log("PRE BSORT STATE", state) let current_members = [...state.members]; console.log("members pre BSO
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(列表){
让成员=[…列表];
设帧=[];
//成员的原始顺序应为列表中的第一帧
框架。推(构件);
让early_退出=false;
设墙=构件长度;
而(!提前退出){
日志(“BSORT中的帧”,帧);
让last_change_index=null;
对于(变量i=0;i成员[i+1].props.style.height){
日志(“交换”,i,i+1);
//如果要交换,这两个元素将显示为黄色,并在x轴上移动
让new_1_yellow=React.cloneElement(
新(1),
{
动画:{x:3},
风格:{背景颜色:“黄色”,高度:新的_1.道具.风格.高度}
}
);
让new_2_yellow=React.cloneElement(
新(二),
{
动画:{x:-3},
风格:{背景颜色:“黄色”,高度:新的_2.道具.风格.高度}
}
);
成员[i+1]=新的黄色;
成员[i]=新的2号黄色;
上次变更指数=i;
框架。推(构件);
//我们将黄色交换的成员改回蓝色
让new_1_blue=React.cloneElement(
新的1号黄色,
{
动画:{x:0},
样式:{背景颜色:“蓝色”,高度:新的1_黄色。道具。样式。高度}
}
);
让new_2_blue=React.cloneElement(
新的2号黄色,
{
动画:{x:0},
样式:{背景颜色:“蓝色”,高度:新的2_黄色。道具。样式。高度}
}
);
成员[i+1]=新的蓝色;
成员[i]=新的蓝色;
//并将此返回蓝色状态添加到列表中
框架。推(构件);
}
否则{
//这里我们将比较的两个元素重新涂成蓝色
让new_1_blue=React.cloneElement(
新(1),
{
样式:{背景颜色:“蓝色”,高度:新的_1.道具.样式.高度}
}
);
让new_2_blue=React.cloneElement(
新(二),
{
风格:{背景颜色:“蓝色”,高度:新的_2.道具.风格.高度}
}
);
成员[i]=新的蓝色;
成员[i+1]=新的蓝色;
//并将此返回蓝色状态添加到列表中
框架。推(构件);
}
}
}
if(上次更改索引==null){
提前退出=真;
}
墙=最后一次变更索引;
}
返回帧;
}
好的,所以我不完全理解这个问题,但听起来您希望一个函数在下一个函数启动之前完成它应该做的事情
async bSort() {
await this.setState(
state => {
console.log("PRE BSORT STATE", state);
let members = state.members;
let states = bubbleSort(members);
return { states: states, animate: true };
},
() => this.animate()
);
}
好的,我不完全理解这个问题,但是听起来好像你想要一个函数在下一个函数被激发之前完成它应该做的事情
async bSort() {
await this.setState(
state => {
console.log("PRE BSORT STATE", state);
let members = state.members;
let states = bubbleSort(members);
return { states: states, animate: true };
},
() => this.animate()
);
}
我认为它的工作方式与您预期的一样,但控制台在它更改后正在检查值 如果
bubbleSort()
原地修改数据,而不是在编辑后返回一个新的原始副本,那么控制台只是保留一个对象引用,然后显示它的当前值