簡體   English   中英

console.log在更改之前打印更改的狀態

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM