[英]console.log prints changed state before changing
我正在尝试通过Drag&Drop用React / Redux重新排列div,我无法解释一个奇怪的行为。 我有以下的reducer(为便于阅读而简化的版本)
代码中间有5个“ console.log”。 当我登录状态或结构时 ,Chrome控制台将打印已经重新排列的版本。 为什么?
export default function reducer(
state={
structures: [],
elementUniqueCounter: 0,
hoveredElement: null,
DnD: {
dragContent: null,
dragOverContent: null,
dragContentTop: true,
dragStructure: null,
dragOverStructure: null,
dragStructureTop: true,
content: null,
mousepositon: {}
}
}, action) {
let DnD = Object.assign({}, state.DnD);
let structs = state.structures.slice();
switch (action.type) {
case "STOP_DRAG_CONTENT":
let cindex_source;
let index_source;
let cindex_target;
let index_target;
let foundTarget = false;
let foundSource = false;
structs.map(function (struct, index) {
struct.content.map(function (content, cindex) {
if(content.id === DnD.dragOverContent.props.id) {
cindex_target = cindex;
index_target = index;
foundTarget = true;
}
if(content.id === DnD.dragContent.props.id) {
cindex_source = cindex;
index_source = index;
foundSource = true;
}
});
});
console.log(state);
console.log(index_source);
console.log(cindex_source);
console.log(index_target);
console.log(cindex_target);
if(index_source !== undefined && cindex_source !== undefined && index_target !== undefined && cindex_target !== undefined) {
let copy = structs[index_source].content.slice(cindex_source, cindex_source+1)[0];
copy.content = DnD.content;
structs[index_source].content.splice(cindex_source, 1);
if (DnD.dragContentTop) {
structs[index_target].content.splice(cindex_target+1, 0, copy);
} else {
structs[index_target].content.splice(cindex_target, 0, copy);
}
}
DnD = {
dragContent: null,
dragOverContent: null,
dragContentTop: true,
dragStructure: null,
dragOverStructure: null,
dragStructureTop: true,
content: null,
mousepositon: {}
};
return {...state, DnD: DnD, structures: structs};
}
return state
}
不是它在发生之前打印了重新排列的版本。 这是因为它正在打印您要突变的对象。 当您在控制台中查看对象时,该突变已经发生。
splice
的使用是变异的。
structs[index_source].content.splice(cindex_source, 1);
if (DnD.dragContentTop) {
structs[index_target].content.splice(cindex_target+1, 0, copy);
} else {
structs[index_target].content.splice(cindex_target, 0, copy);
}
编辑:
上面的突变实际上是在改变state.structures
的嵌套属性。 这是因为.slice()返回原始对象的浅表副本。
slice()方法将数组的一部分的浅表副本返回到从头到尾选择的新数组对象中(不包括end)。 原始数组将不会被修改。
浅表副本中的对象只是state.structures
对象的state.structures
。 因此,当您使用.splice()
,您会突变那些引用的值。
这是一个片段来说明这一点。 在console.log
运行它。
const people = [ { name: "Joe", age: "52" }, { name: "Sally", age: "48" } ]; const clonedPeople = people.slice(); console.log("people === clonedPeople: ", people === clonedPeople); console.log("people[0] === clonedPeople[0]: ", people[0] === clonedPeople[0]); const deeplyClonedPeople = JSON.parse(JSON.stringify(people)); console.log("people[0] === deeplyClonedPeople[0]: ", people[0] === deeplyClonedPeople[0]);
希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.