ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • immer란?
    API/immer 2022. 9. 13. 17:03

    immer

    리액트에서 가장 중요한 점은 업데이트를 하고자하는 객체, 배열은 직접 수정하면 안되고 불변성을 지켜주면서 업데이트를 해줘야한다.
    아래 코드는 대표적인 예이다.

    const user = {
      name:'JACK',
      age:22,
    }
    
    const newUser = {
      ...user,
      age:22
    }

    이처럼 리액트는 불변성이 매우 중요한데 위의 예시처럼 간단한 객체 혹은 배열이라면 얕은 복사를 통해 수정하는 것은 어렵지가 않다.
    하지만 위처럼 코드가 단순하지 않다면 코드가 매우 길어지며 복잡해지기 시작한다.

    만약 객체 속에서 아이디를 찾은다음에 그 아이디가 작성한 게시글을 찾아 해당 게시글에 댓글을 추가하는 코드를 작성할 때 불변성을 지키며 코드를 작성하면 아래와 같다.

    // state에서 수정하고자 하는 ID의 index찾기
    const index = state.posts.findIndex((user)=>user.id===action.data.postId);
    // state에서 index에 해당하는 글을 얕은 복사를 사용하여 복사
    const post = {...state.Posts[index]};
    // 복사해온 글이 갖고 있는 comments를 복사해온뒤 새로운 더미데이터를 추가
    post.comments = [...post.comments, dummy(action.data.content)]
    // 수정하기 전 state를 모두 복사해온다
    const mainPosts = [...state.Posts];
    // 복사해온 전체 state 중 수정을 완료한 게시글에 index로 접근하여 직접 수정
    mainPosts[index] = post;
    // 수정전 state를 복사해온 뒤 수정된 게시글을 반환
    return {
      ...state,
      mainPosts,
    }

    이처럼 불변성을 지키며 객체, 배열을 수정하면 위 처럼 가독성도 안좋아지며, 복잡한 코드를 생성하게 된다. 이러한 현상을 없애기 위해 immer라는 라이브러리가 있다.

    immer란?

    immer는 우리가 상태를 업데이트 할 때 불변성을 신경쓰지 않고 코드를 작성해주면 immer에서 자동으로 불변성을 지켜주게 된다.

    immer의 produce는 baseState라는 수정 전상태와 draftState라는 어떻게 업데이트를 할지 정의하는 두개의 파라미터를 갖고있다.

    produce(baseState, recipe:(draftState)=>void):nextState

    immer를 사용하여 간단한 객체를 수정해보자

    const state = {
      name:'JACK',
      age:22,
    }
    
    const newUser = produce(state,(draft)=> draft.age = 30)

    이렇게 draft를 사용하면 이전상태를 얕은복사하지 않고 바로 바꿔주면 immer라이브러리가 알아서 불변성을 지켜 값을 변경해주게 된다.

    그렇다면 불변성을 지키면서 바꿔준 복잡한 코드를 immer를 사용하여 변경해보자.

    // draft를 사용하여 수정하고자 하는 게시글을 찾아온다.
    const post = draft.Posts.find((user)=>user.id===action.data.postId);
    // 찾아온 게시글에 unshift를 사용하여 직접 수정
    post.comments.unshift(dummy(action.data.content));

    아까의 복잡한 코드가 immer 라이브러리를 사용하니 두줄의 코드로 줄게되었다.
    이처럼 immer는 사용자가 불변성을 지키지 않고 작성하여도 immer자체에서 불변성에 맞게 알아서 변경해주는 매우 편리한 라이브러리이다.

    immer를 사용할 때는 불변성을 지키지 않고 수정하는 방법이 권장된다. 그렇기 때문에 filter처럼 새로운 배열을 반환하는 것보다는 기존의 배열을 수정하는 splice 같은 함수를 사용하는 것이 더 옳바른 방법이다.

Designed by Tistory.