StarWarsAPI : 2021.02.28 Redux dispatch Action Twice ~ Redux Removing Element from Nested Objects

오범준·2021년 2월 28일
0

initial State in Redux

const initialState = {
    input : '' ,
    byId : {
        // commentId == postID
        "commentId" : {
            commentId : "commentId",
            commentText : ".....",
            createdAt : new Date()
        },
        "CxYDfUKkx" : {
            commentId :"CxYDfUKkx" ,
            commentText :"안녕" ,
            contentId :"falcon9" ,
            createdAt :"2021-02-27T15:43:52.606Z"
        }
    },
    commentIds : []
}

#### What I am Trying to do : delete certain 'comment' in initialState.byId by its 'commentId'

❤ Action Creator , Action

export const removeComment = ( commentId ) => ({
    type : REMOVE_COMMENTS ,
    payload : commentId 
})

1st : Spread Operator

❤ Reducer

const  removedId  = action.payload
            let copy = Object.assign({}, state.byId)
            console.log("copy", copy[removedId])
            delete copy[removedId]
            return copy

❤ Error

TypeError
Cannot read property '5EyLC3mg5' of undefined

❤ Result
Actually, According comment is 'deleted'

❤ Why Wrong
this is Wrong approach, because you are returning
different form of state in comparison to 'initialState'

form of initialstate

const initialState = {
    input : '' ,
    byId : {
        // commentId == postID
        "commentId" : {
            commentId : "commentId",
            commentText : ".....",
            createdAt : new Date()
        },
        "CxYDfUKkx" : {
            commentId :"CxYDfUKkx" ,
            commentText :"안녕" ,
            contentId :"falcon9" ,
            createdAt :"2021-02-27T15:43:52.606Z"
        }
    },
    commentIds : []
}

after

{
        // commentId == postID
        "commentId" : {
            commentId : "commentId",
            commentText : ".....",
            createdAt : new Date()
        },
        "CxYDfUKkx" : {
            commentId :"CxYDfUKkx" ,
            commentText :"안녕" ,
            contentId :"falcon9" ,
            createdAt :"2021-02-27T15:43:52.606Z"
        }
    }

that, is you are not maintiaing the 'Immutability' of React

Immutability : you cannot mutate value after you declare it



2nd Trial : Immer.js

❤ Reducer

case REMOVE_COMMENTS :
            const  removedId  = action.payload
            // let copy = Object.assign({}, state.byId)
            // console.log("copy", copy[action.payload])
            // delete copy[action.payload]
            // return copy
            return produce(state, draft => {
                delete draft.byId[removedId] 
            });

❤ Error

TypeError
Cannot read property 'commentId' of undefined

Location 
personal_starwarsapi/./src/components/Comment.js:45:18

❤ Result
Actually, According comment is 'deleted'

❤ Problem Anaysis
Since, 'Action' & 'Dispatch' is working, it doesn't seems to be
related with 'Redux'


Rather, it seems to be related with other parts

It was other helper function, which was adding 'undefined' as 'comment', which does not have 'commentId' property


Helper function where gets list of commentIds

// Helper functions
export const getCommentsOfContent = (commentIds, commentState) => {
    let commentInfos = []
    commentIds.forEach((commentId) => {
        // if(commentState.byId[commentId] ){
        commentInfos.push(commentState.byId[commentId])
        // }
    })
    return commentInfos
}

Solution : add (" commentState.byId[commentId] && " )

// Helper functions
export const getCommentsOfContent = (commentIds, commentState) => {
    let commentInfos = []
    commentIds.forEach((commentId) => {
        // if(commentState.byId[commentId] ){
        commentState.byId[commentId] && commentInfos.push(commentState.byId[commentId])
        // }
    })
    return commentInfos
}
profile
Dream of being "물빵개" ( Go abroad for Dance and Programming)

0개의 댓글