인프런 커뮤니티 질문&답변

uphoon님의 프로필 이미지

작성한 질문수

[리뉴얼] React로 NodeBird SNS 만들기

concat, push map 사용시 오류에 관하여 질문

작성

·

273

0

게시물 더미데이터 추가 될때 concat을 사용하던데 어차피 immer 통해서 불변성이 유지가 되는거라면 push를 사용해도 된다고 생각되어서 push 를 사용해봤더니 index.js에서 map부분에서 오류가 나던데 그 이유를 알 수 있을까요?

답변 1

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

코드 보여주세요

uphoon님의 프로필 이미지
uphoon
질문자

 

import shortId from 'shortid';
import produce from 'immer';
import faker from 'faker';

export const initialState = {
    mainPosts: [{
        id: 1,
        User: {
            id: 1,
            nickname: '제로초',
        },
        content: '첫번째 게실글 #해시태그 #익스프레스',
        Images: [{
            id: shortId.generate(),
            src: 'https://bookthumb-phinf.pstatic.net/cover/137/995/13799585.jpg?udate=20180726',
        }, {
            id: shortId.generate(),
            src: 'https://gimg.gilbut.co.kr/book/BN001958/rn_view_BN001958.jpg',
        }, {
            id: shortId.generate(),
            src: 'https://gimg.gilbut.co.kr/book/BN001998/rn_view_BN001998.jpg',
        }],
        Comments: [{
            id: shortId.generate(),
            User: {
                id: shortId.generate(),
                nickname: 'nero',
            },
            content: '우와우와'
        }, {
            id: shortId.generate(),
            User: {
                id: shortId.generate(),
                nickname: 'wi',
            },
            content: '힘내자'
        }],
    }],
    imagePath: [],
    hasMorePosts: true,
    loadPostsLoading: false,
    loadPostsDone: false,
    loadPostsError: null,
    addPostLoadding: false,
    addPostDone: false,
    addPostErr: null,
    removePostLoadding: false,
    removePostDone: false,
    removePostErr: null,
    addCommentLoadding: false,
    addCommentDone: false,
    addCommentErr: null,
}


export const getDemmuyPost = (number) => Array(number).fill().map(() => ({
    id: shortId.generate(),
    User: {
        id: shortId.generate(),
        nickname: faker.name.findName(),
    },
    content: faker.lorem.paragraph(),
    Images: [{
        src: faker.image.image(),
    }],
    Comments: [{
        User: {
            id: shortId.generate(),
            nickname: faker.name.findName(),
        },
        content: faker.lorem.sentence(),
    }],
}))

export const LOAD_POSTS_REQUEST = 'LOAD_POSTS_REQUEST';
export const LOAD_POSTS_SUCCESS = 'LOAD_POSTS_SUCCESS';
export const LOAD_POSTS_FAILURE = 'LOAD_POSTS_FAILURE';

export const ADD_POST_REQUEST = 'ADD_POST_REQUEST'
export const ADD_POST_SUCCESS = 'ADD_POST_SUCCESS'
export const ADD_POST_FAILURE = 'ADD_POST_FAILURE'

export const REMOVE_POST_REQUEST = 'REMOVE_POST_REQUEST'
export const REMOVE_POST_SUCCESS = 'REMOVE_POST_SUCCESS'
export const REMOVE_POST_FAILURE = 'REMOVE_POST_FAILURE'

export const ADD_COMMENT_REQUEST = 'ADD_COMMENT_REQUEST'
export const ADD_COMMENT_SUCCESS = 'ADD_COMMENT_SUCCESS'
export const ADD_COMMENT_FAILURE = 'ADD_COMMENT_FAILURE'



export const addPostAction = (data) => {
    console.log(data)
    return {
        type: ADD_POST_REQUEST,
        data
    }
}

export const addCommentAction = (data) => {
    console.log(data)
    return {
        type: ADD_COMMENT_REQUEST,
        data
    }
}

const dummyPost = (data) => (
    {
        id: data.id,
        content: data.content,
        User: {
            id: 1,
            nickname: '제로초',
        },
        Images: [],
        Comments: [],
    }
)

const dummyComment = (data) => (
    {
        id: shortId.generate(),
        content: data,
        User: {
            id: 1,
            nickname: '제로초',
        },
    }
)

const reducer = (state = initialState, action) => {
    return produce(state, (draft) => {
        switch (action.type) {
            case LOAD_POSTS_REQUEST:
                draft.loadPostsLoading = true;
                draft.loadPostsDone = false;
                draft.loadPostsError = null;
                break;
            case LOAD_POSTS_SUCCESS:
                draft.loadPostsLoading = false;
                draft.loadPostsDone = true;
                draft.mainPosts = action.data.concat(draft.mainPosts);
                draft.hasMorePosts = draft.mainPosts.length < 50;
                break;
            case LOAD_POSTS_FAILURE:
                draft.loadPostsLoading = false;
                draft.loadPostsError = action.error;
                break;

            case ADD_POST_REQUEST:
                draft.addPostLoadding = true
                draft.addPostDone = false
                draft.addPostErr = null

                break;
            case ADD_POST_SUCCESS:
                draft.addPostLoadding = false
                draft.addPostDone = true
                draft.mainPosts.unshift(dummyPost(action.data))

                break;
            case ADD_POST_FAILURE:
                draft.addPostLoadding = false
                draft.addPostErr = action.err

                break;
            case REMOVE_POST_REQUEST:
                draft.removePostLoadding = true
                draft.removePostDone = false
                draft.removePostErr = null
                break;

            case REMOVE_POST_SUCCESS:
                draft.removePostLoadding = false
                draft.removePostDone = true
                draft.mainPosts = state.mainPosts.filter((item) => item.id !== action.data)
                break;
            case REMOVE_POST_FAILURE:
                draft.removePostLoadding = false
                draft.removePostErr = action.err
                break;
            case ADD_COMMENT_REQUEST:
                draft.addCommentLoadding = true
                draft.addCommentDone = false
                draft.addCommentErr = null
                break;
            case ADD_COMMENT_SUCCESS:
                const post = draft.mainPosts.find((item) => item.id === action.data.postId)
                post.Comments.unshift((dummyComment(action.data.content)))

                draft.addCommentLoadding = false
                draft.addCommentDone = true
                break;
            case ADD_COMMENT_FAILURE:
                draft.addCommentLoadding = false
                draft.addCommentErr = action.error

            default:
                return state
        }
    })
}

export default reducer

LOAD_POSTS_SUCCESS 부분에서 굳이 concat을 써야 하는이유가 있을까요 ?

불변성이 유지된다면 push를 써도 가능할것 같은데

uphoon님의 프로필 이미지
uphoon
질문자

image선생님 이런식으로 push 사용시 map is not function 이 뜨는데 이유를 알수 있을까요?

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

완전 잘못 생각하신 것이 있는데요. push는 배열을 return하지 않습니다.

uphoon님의 프로필 이미지
uphoon
질문자

아 선생님 그러면 https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/push 이 내용을 제가 잘못 이해한걸까요 그리고

 case FOLLOW_SUCCESS:
                draft.followingLoading = false
                draft.followingDone = true
                draft.me.Followings.push({ id: action.data })
                break;

이부분에서는 push를 사용해서 배열을 반환하는건 아닌걸까요?

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

push는 배열의 새로운 길이(length)를 반환한다고 되어있습니다. 거기다 FOLLOW_SUCCESS에서는 push가 반환하는 값을 사용하지 않습니다. immer는 draft 값을 바꿔주면 알아서 불변성을 지켜주는 라이브러리입니다.

uphoon님의 프로필 이미지
uphoon
질문자

아 선생님 연구 끝에 알아냈습니다. push를 사용하면 mainpost 밑에 새로운 배열로 더미데이터 들이 들어갑니다 그래서 concat은 새로운 더미데이터 배열 요소가 들어와도 아예 새롭게 배열로 만들어주는데 push 사용하려면 더미데이터가 나오는게 배열을 해체 시키면 concat대신에 사용가능하네요.

            case LOAD_POSTS_SUCCESS:
                draft.loadPostsLoading = false;
                draft.loadPostsDone = true;
                draft.mainPosts.push(...action.data)
                draft.hasMorePosts = draft.mainPosts.length < 50;
                break;

이런식으로 하니 작동이 되네요 ㅎㅎ

//push

const array1 = ['a', 'b', 'c'];
const array2 = ['d', 'e', 'f'];
array1.push(array2);

console.log(array1);

//> Array ["a", "b", "c", Array ["d", "e", "f"]]

//concat
const array1 = ['a', 'b', 'c'];
const array2 = ['d', 'e', 'f'];
const array3 = array1.concat(array2);

console.log(array3);

//> Array ["a", "b", "c", "d", "e", "f"]
uphoon님의 프로필 이미지

작성한 질문수

질문하기