react

Recoil 에서 Selector 기능 get, set 사용법

YG - 96년생 , 강아지 있음, 개발자 희망 2021. 12. 4. 10:12

Selector 란

Selector는 Recoil에서 함수나 파생된 상태를 나타낸다. 주어진 종속성 값 집합에 대해 항상 동일한 값을 반환하는 부작용이 없는 "순수함수"

 

Selector 을 사용해야 하는 이유

최소한의 상태 집합만 atoms에 저장하고 다른 모든 파생되는 데이터는 selectors에 명시한 함수를 통해 효율적으로 계산함으로써 쓸모없는 상태의 보존을 방지한다.

 

https://recoiljs.org/ko/docs/api-reference/core/selector

 

selector(options) | Recoil

Selector는 Recoil에서 함수나 파생된 상태를 나타낸다. 주어진 종속성 값 집합에 대해 항상 동일한 값을 반환하는 부작용이 없는 "순수함수"라고 생각하면 된다. get 함수만 제공되면 Selector는 읽기

recoiljs.org

 

Get?

get - 파생된 상태의 값을 평가하는 함수. 값을 직접 반환하거나 비동기적인 Promise나 또는 같은 유형을 나타내는 다른 atom이나 selector를 반환할 수 있다. 첫 번째 매개변수로 다음 속성을 포함하는 객체를 전달한다

 

Set?

set? - 이 속성이 설정되면 selector는 쓰기 가능한 상태를 반환한다. 첫번째 매개변수로 콜백 객체와 새로 입력 값이 전달된다. 사용자가 selector를 재설정할 경우 새로 입력 값은 T 타입의 값 또는 DefaultValue 타입의 객체일 수 있다. 콜백에는 다음이 포함된다

 

 

사용 예시

 

App.tsx

import React from "react";
import { useRecoilState, useRecoilValue } from "recoil";
import { hourSelector, minuteState } from "./atoms";

function App() {
  const [minutes, setMinutes] = useRecoilState(minuteState);
  const [hours, setHours] = useRecoilState(hourSelector);
  const onMinuteChange = (event: React.FormEvent<HTMLInputElement>) => {
    const {
      currentTarget: { value },
    } = event;
    setMinutes(+value);
  };
  const onHoursChange = (event: React.FormEvent<HTMLInputElement>) => {
    const {
      currentTarget: { value },
    } = event;
    setHours(+value);
  };
  return (
    <div>
      <input
        onChange={onMinuteChange}
        value={minutes}
        type="number"
        placeholder="Minutes"
      ></input>
      <input
        value={hours.toFixed(0)}
        onChange={onHoursChange}
        type="number"
        placeholder="Hours"
      ></input>
    </div>
  );
}

export default App;

 

Atoms.ts

import { atom, selector } from "recoil";

export const minuteState = atom({
  key: "minutes",
  default: 0,
});

export const hourSelector = selector<number>({
  key: "hours",
  get: ({ get }) => {
    const minutes = get(minuteState) / 60;
    return minutes;
  },
  set: ({ set }, newValue) => {
    // console.log(Number(newValue));
    const minutes = Number(newValue) * 60;
    set(minuteState, minutes);
  },
});

 

예시를 보면 minuteState에서 분의 입력을 받아서 저장을 한 뒤

 

hourSelector에서 먼저 get 함수로 minutesState 값을 가져온 후 값/60 을 하여 hours 를 리턴한다.

 

또한 set함수에서는 hours input에 입력되는 값을 인지한 뒤 newValue 값을 받아 *60을 해주어 minute 값을 리턴하여

 

set(변하고자하는 atom값 , 변하게 할 값) 을 이용하여 set(minuteState , minutes)를 하였다.

 

App.tsx 에서는 const [hours,setHours] = useRecoilState(hourSelector) 을 하여

 

hours 에서는 get에서 리턴된 값을 받도록 되어 있고

 

setHours 에서는 Selector 안의 set에서의 시간을 분으로 바꾸는 함수를 실행해준다.