console.log在更改之前打印已更改的状态

时间:2017-11-16 15:43:35

标签: reactjs redux

我正试图通过Drag& Drop重新排列div与React / Redux,并且有一个奇怪的行为,我无法解释。我有以下减速机(可读性简化版)

代码中间有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
}

1 个答案:

答案 0 :(得分:1)

并不意味着它会在重新排列的版本发生之前打印出来。它正在打印一个你正在改变的对象。当你在控制台中查看对象时,突变已经发生。

使用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()方法将数组的一部分的浅表副本返回到从头到尾选择的新数组对象(不包括结尾)。原始数组不会被修改。

浅拷贝中的对象只是指向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]);




希望这有帮助!