[英]console.log prints changed state before changing
I'm trying to rearrange div's with React/Redux via Drag&Drop and there is a strange behavoir that i cant explain. 我正在尝试通过Drag&Drop用React / Redux重新排列div,我无法解释一个奇怪的行为。 I have the following reducer (reduced version for readability)
我有以下的reducer(为便于阅读而简化的版本)
There are 5 "console.log" around the middle of the code. 代码中间有5个“ console.log”。 When i log state or structs the chrome console will print the already rearrange version.
当我登录状态或结构时 ,Chrome控制台将打印已经重新排列的版本。 why?
为什么?
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
}
It's not that it is printing the rearranged version before it happens. 不是它在发生之前打印了重新排列的版本。 It is that it is printing an object that you are mutating.
这是因为它正在打印您要突变的对象。 By the time you look at the object in the console the mutation has already occurred.
当您在控制台中查看对象时,该突变已经发生。
The use of splice
is mutating. 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);
}
EDIT: 编辑:
The above mutation is actually mutating the nested properties of state.structures
. 上面的突变实际上是在改变
state.structures
的嵌套属性。 This is happening because .slice() returns a shallow copy of the original object. 这是因为.slice()返回原始对象的浅表副本。
The slice() method returns a shallow copy of a portion of an array into a new array object selected from begin to end (end not included).
slice()方法将数组的一部分的浅表副本返回到从头到尾选择的新数组对象中(不包括end)。 The original array will not be modified.
原始数组将不会被修改。
The objects in the shallow copy are just pointers to the objects in state.structures
. 浅表副本中的对象只是
state.structures
对象的state.structures
。 So when you use .splice()
, you mutate those referenced values. 因此,当您使用
.splice()
,您会突变那些引用的值。
Here is a snippet to illustrate this. 这是一个片段来说明这一点。 Run it an look at the
console.log
. 在
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]);
Hope this helps! 希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.