Recoil의 Selector를 사용해 상호작용하는 상태 설정하기

silver·2024년 5월 19일

React

목록 보기
1/3

사례

POS프로그램을 개발하던 중 장바구니에 담긴 상품의 정보를 저장하는 shoppingCart 상태가 있고, 결제정보를 저장하는 paymentInfo 상태가 있다. 이 때 shoppingCart에 담긴 상품에 변화가 있을 때 paymentInfo를 기본값으로 변경하려 한다.

또, paymentInfo의 totalAmount는 shoppingCart에 담긴 상품의 가격과 수량을 곱한 값이 저장되도록 하고, shoppingCart가 변경될 때마다 자동으로 업데이트되도록 하려 한다. paymentInfo와 shoppingCart 상태의 형태는 아래와 같다.

interface IShoppingCartProduct {
  name:string;
  number:number;
  quantity:number;
  price:number;
}

interface IPaymentInfo {
    method: methodType;
  discountType: 'percentage' | 'amount' | '';
  totalAmount: number;
  discountAmount: number;
  discountValue: number;
  chargedAmount: number;
  discountReason: string;
  ETCReason: string;
}

const defaultPaymentInfo : IPaymentInfo = {
        method: '',
      discountType: '',
      totalAmount: 0,
      discountAmount: 0,
      discountValue: 0,
      chargedAmount: 0,
      discountReason: '',
      ETCReason: '',
}

const shoppingCartAtom = atom<IShoppingCartProduct[]>({
  key : 'shoppingCart',
  default : [],
});

const paymentInfoAtom = atom<IPaymentInfo>({
  key : 'paymentInfo',
  default : defaultPaymentInfo,
} 

여기에 selector를 이용하면 두개의 상태를 연결해서 상태가 변경될 때 마다 쌍이되는 상태를 변경시킬 수 있다.


const shoppingCartSelector = selector<IShoppingCartProduct[]>({
  key : 'shoppingCartSelector',
  get : ({get})=>{
    return get(shoppingCartAtom);
  },
  set : ({set,reset})=>{
    set(shoppingCartAtom, newValue);
    reset(paymentInfoAtom);
  }
});

const paymentInfoSelector = selector<IPaymentInfo>({
  key: 'paymentInfoSelector',
  get: ({ get }) => {
    const products = get(shoppingCartAtom);
    const paymentInfo = get(paymentInfoAtom);
    const totalAmount = products.reduce((total, product) => total + product.price * product.quantity, 0);
    return {
      ...paymentInfo,
      totalAmount,
      chargedAmount: totalAmount,
    };
  },
  set: ({ set }, newValue) => {
    set(paymentInfoAtom, newValue);
  },
});

get

selector에서 get은 useRecoilValue,useRecoilState의 첫번째 요소를 통해 해당 selector를 불러올 때 리턴되는 값을 설정한다.

shoppingCartSelector의 get 필드에는 shoppingCartAtom의 상태를 그대로 불러오도록 설정했다.

paymentInfoSelector의 get 필드에는 shoppingCartAtom과 paymentInfoAtom을 불러온다.
그리고 shoppingCartAtom에 저장되어 있는 상품들의 가격과 수량을 곱해서 총합한 값을 totalAmount 변수에 할당하고 기존의 결제정보에 totalAmount와 chargedAmount에 totalAmount를 할당한 값을 불러온다.

set

set은 useSetRecoilState,useRecoilState의 두번째 요소로 주어지는 함수를 사용할 때 전달할 값을 설정한다.

shoppingCartSelector의 set 필드에는 전달받은 newValue를 shoppingCartAtom에 입력하고,
paymentInfoAtom에는 reset메서드를 사용해 default 값으로 되돌린다.

paymentInfoSelector의 set 필드에는 전달받은 값을 그대로 paymentInfoAtom에 전달하도록 설정했다.

0개의 댓글