recoil atom에서 default가 여러 개일 때 하나만 수정하기

김은호·2023년 3월 1일
2

기존에 사용하던 방법

// atom.ts
exprot const exampleAtom({
  key: 'myAtom',
  default: {
   	foo: val1,
    bar: val2,
    baz: val3,
  }
})

// index.tsx
const setAtom =useSetRecoilState(exampleAtom);

const onChangeAtom = (value: number) => {
 	setAtom(prev => {
     	return {
          ..prev,
          bar: anotherVal,
        }
    }
}

const obj1 = {a: 1, b: 2, c: 3}일 때
const obj2 = {...obj1, b: 123}을 하면 obj2가 {a: 1, b: 123, c: 3}이 되는 방법을 이용하였다.

selector 이용

exprot const exampleAtom({
  key: 'myAtom',
  default: {
   	foo: val1,
    bar: val2,
    baz: val3,
  }
})

export const mySelector = selector({
  key: 'MySelector',
  get: ({get}) => get(exampleAtom),
  set: ({set}, newValue) => set(exampleAtom, {...get(exampleAtom), foo: newValue)},
})

사용하는 원리는 같지만 실제 코드를 작성하는 부분에서는 setAtom(value)만 입력하면 되므로 코드의 양이 줄어든다.

2023.3.7 수정

실제 사용하려고 해보니 에러가 뜬다. 그래서 다시 공식 문서를 뒤적뒤적 하여 정리하니 다음과 같았다.

exprot const exampleAtom({
  key: 'myAtom',
  default: {
   	foo: val1,
    bar: val2,
    baz: val3,
  }
})

export const mySelector = selector({
  key: 'MySelector',
  get: ({get}) => {
   const copyAtom = get(exampleAtom);
    return copyAtom.foo;
  },
  set: ({set}, newValue) => {
   set(exampleAtom, (prev) => {
    return {
     ...prev,
     foo: newValue.toString();
    };
   }
  },
});

중요한 것은 foo: newValue.toString(); 처럼 업데이트하는 값의 타입을 지정해줘야 한다. 아니면 ts2345 에러가 뜬다.

(참고로 number이라면 foo: +newValue) 식으로 하면 된다!)

결론

selector을 이용하면 실제 set을 하는 코드의 양은 줄어들지만 바꿔야 하는 값이 많다면 여러 개의 selector을 선언해야 한다.

바꾸는 default의 개수에 따라 적절하게 사용하면 될 것 같다.

0개의 댓글