새 대상을 만들 때 {...state,hoge}를 일일이 쓰고 싶지 않은 당신, Immerjs

대상 독자


React Hook에 사용된 Reducter 함수처럼 기존 객체를 기반으로 새 객체를 만들 때 스프레드시트({...state, hoge} 의 쓰기 방법)로 쓰면서 코드가 지루하고 곤란해지는 사람.
React Hook의 Reducter 함수를 사용하여 설명하므로 React Hook에서 Reducter 함수를 작성한 사람을 대상으로 합니다.
https://ja.reactjs.org/docs/hooks-reference.html#usereducer

Reducter를 사용하여 스프레드시트로 새 State를 반환하는 방법


React Hook에서 Reducter 함수를 만들 때 Action type에 따라 대부분의 경우 기존 State와 다른 새 state를 구현할 수 있다고 생각합니다.
const initialState = {
  isLoading: false,
  hoge: "hoge"
}
reducer(state = initialState, action) => {
  switch (action.type) {
    case "UPDATE":
      return {...state, hoge: "new_hoge"};
    default:
      return state;
  }
}
위에서 말한 바와 같이 상태 구조가 간단했으면 좋겠지만 등급이 깊은 상태라면 어떨까.
const initialState: State = {
  hoge1: {
    fuga1: {
      piyo1: "test",
      piyo2: "test",
    },
    fuga2: "test",
  },
  hoge2: {
    fuga3: "test",
  },
};

const todos = (state = initialState, action) => {
  switch (action.type) {
    case "UPDATE":
      return {
        ...state,
        hoge1: {
          ...state.hoge1,
          fuga1: {
            ...state.hoge1.fuga1,
            piyo1: "new_test",
          },
        },
      };
    default:
      return state;
  }
};
위에서 말한 바와 같이 원본state.hoge1.fuga1.piyo1의 값을 바꾸려면 {...state,hoge:new hoge〃}와 같은 전자 표를 써야 한다.

Immerjs에서 새 State 객체 생성


따라서 다음 Immerjs 프로그램 라이브러리를 사용하여 새로운 State 대상을 이세계판으로 만듭니다.
https://github.com/immerjs/immer
import produce from "immer";

const initialState: State = {
  hoge1: {
    fuga1: {
      piyo1: "test",
      piyo2: "test",
    },
    fuga2: "test",
  },
  hoge2: {
    fuga3: "test",
  },
};

const todos = (state = initialState, action) => {
  switch (action.type) {
    case "UPDATE":
      return produce(state, (draftState) => {
        draft.hoge1.fuga1.piyo1 = "new_test";
      });
    default:
      return state;
  }
};
제품이라는 함수는 간이다.
첫 번째 파라미터를 통해 전달된 대상은draftState로 두 번째 파라미터로 전달되는 방법입니다.
이 방법으로 속성을 다시 쓰지 않으면 기존state에 영향을 주지 않는 상황에서 새로운 대상을 생성할 수 있습니다.
const newState = produce(state, (draftState) => {
  draft.hoge1.fuga1.piyo1 = "new_test";
});
console.log(state.hoge1.fuga1.piyo1); // test(値はそのまま)
console.log(newState.hoge1.fuga1.piyo1); // new_test(値が更新されている)

총결산


Immerjs에 관해서는 처음에는 함수로 이세계의 대상을 만드는 데 익숙하지 않을 수도 있지만, 습관이 되면 전자 표의 문법보다 더욱 유창해질 수 있으니 꼭 시도해 보세요.

좋은 웹페이지 즐겨찾기