티스토리 뷰

Javascript

[React] Recoil

codeyun2 2023. 4. 21. 21:13

atom, selector로 상태를 정의하고 useRecoilState 등으로 불러와서 사용

 

상태 정의

atom

기본적인 상태 단위

  • key: 상태를 구분할 특수한 값
  • default: 초기값
const fontSizeState = atom ({
  key: 'fontSizeState',
  default: 초기값
})

...

const [fontSize, setFontSize] = useRecoilState(fontSizeState);

 

  • effects: 부수 효과. localStorage 저장이 필요한 경우 사용
    • setSelf: 로컬 키를 불러와서 상태로 저장하는 함수
    • onSet: 상태 변경 시 실행될 함수
      • newValue: 새 상태
      • oldValue: 기존 상태
      • isReset: 초기화 여부(set함수로 default값을 저장하면 T로 인식)
const cartState = atom ({
  key: 'fontSizeState',
  default: 초기값,
  effects: ({ setSelf, onSet }) => {
    const savedValue = localStorage.getItem('cart')
    // 로컬에 값이 있으면 상태에 그 값 저장
    if (savedValue !== null) setSelf(JSON.parse(savedValue));
    
    // isReset이 T면 로컬 지우고, F면 상태 저장하기
    // isReset은 setState(default)하면 T로 인식됨
    onSet((newValue, oldValue, isReset) => {
      isReset
      ? localStorage.removeItem('cart')
      : localStorage.setItem('cart', newValue)
    })
  }
})

 

보통 로컬 저장 함수를 따로 정의하여 사용한다

const localStorageEffect = (key) => ({ setSelf, onSet }) => {
  const savedValue = localStorage.getItem(key)
  if (savedValue !== null) setSelf(JSON.parse(savedValue));

  onSet((newValue, oldValue, isReset) => {
    isReset
    ? localStorage.removeItem(key)
    : localStorage.setItem(key, newValue)
  })
}


const cartState = atom ({
  key: 'fontSizeState',
  default: [],
  effects: localStorageEffect('cart')
})

 

selector

파생 상태를 계산하기 위한 순수 함수

상태(atom, selector)를 기반으로 만드는 새로운 상태 → 기존 상태에 의존

상태 변화에 반응하여 자동으로 값을 업데이트하고 컴포넌트에 공유

 

  • key: 상태를 구분할 특수한 값
  • get
    • atom, selector을 필요한 형태로 변화시키는 함수 => 상태
    • atom을 불러올 때 get(atom) 형태로 불러서 값에 접근
      • get으로 불러오지 않으면 key를 포함한 atom 자체를 불러옴
  • set: selector를 바꾸는 함수
    • 설정하지 않을 경우 read-only로 selector를 바꿀 수 없음(의존하고 있는 상태 변경에 따른 변화만 일어남)
    • set을 자주 사용하지는 않음
const fontSizeLabelState = selector({
  key: 'fontSizeLabelState',
  get: ({get}) => {
    const fontsize = get(fontSizeState);
    const unit = 'px';
    return `${fontSize}${unit}`;
  })
})

 

selectorFamily

고차 함수로 인자를 받아 selector를 여러 형태로 이용

const fontSizeLabelState = selectorFamily({
  key: 'fontSizeLabelState',
  get: (unit) => ({get}) => {
    const fontsize = get(fontSizeState);
    return `${fontSize}${unit}`;
  })
})

 

상태 사용

useRecoilState(fontSizeState)

useState와 동일하게 배열로 값과 set함수를 받아서 사용

const [fontSize, setFontSize] = useRecoilState(fontSizeState)

 

useRecoilValue(fontSizeLabelState)

값만 필요한 경우 사용

const fontSizeLabel = useRecoilValue(fontSizeLabelState)

 

useSetRecoilState(fontSizeLabelState)

셋함수만 필요한 경우 사용

const fontSizeLabel = useSetRecoilState(fontSizeLabelState)

 

useRecoilValueLoadable

상태 내부에서 api 요청을 보내는 경우 사용(비동기)

- 기존 상태를 받아 api 요청을 보내는 selector의 값을 받을 때 사용

const currentWeather = useRecoilValueLoadable(weatherState)

 

 

 

 

2023.04.21

코드스테이츠 리코일 특강

댓글
공지사항