Web-Frontend/React.js

[React.js] Recoil - Selector

서노리 2023. 4. 18. 01:36
반응형

Selector

  • recoil에서의 함수 또는 파생된 상태
  • 파생된 상태란 atom의 상태에서 파생된 데이터, 즉 atom의 상태에 의존하는 동적인 데이터를 의미
  • 주어진 atom의 상태에 대해 항상 동일한 값을 반환하는 순수함수

 

Selector를 사용하는 이유?

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


Selector 생성하기

export const hourSelector = selector<number>({
  key: "hours",
  get: ({ get }) => {
    const minutes = get(minuteState);
    return minutes / 60;
  },
  set: ({ set }, newValue) => {
    const minutes = Number(newValue) * 60;
    set(minuteState, minutes);
  },
});
  • key는 내부적으로 atom을 식별하는데 사용되는 문자열이다.
  • get은 파생된 상태의 값을 평가하는 함수로, 매개변수로 콜백객체를 받는데, 콜백 객체 내의 get 메소드를 이용하여 다른 atom이나 selector를 가져온다.
  • set 속성이 설정되면 selector는 쓰기 가능한 상태가 된다. set은 콜백객체와 새로운 값 2가지를 매개변수로 받는데, 콜백 객체 내의 set 메소드를 이용하여 다른 atom의 값을 새로운 값으로 변경시킨다.

Selector 사용하기

const [hours, setHours] = useRecoilState(hourSelector);

 

get과 set이 둘다 있는 selector를 사용하기 위해서는 useRecoilState를 사용한다. get만 있는 selector의 경우 useRecoilValue를 사용해도 무방하다.

 

hours에는 hourSelector의 get에서 리턴된 값이 저장되고, setHours는 set에서 시간을 분으로 바꾸는 함수를 실행한다.

 

※ 예제 코드

// 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);
  },
});
// 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); // String을 Number로 변환
  };
  const onHoursChange = (event: React.FormEvent<HTMLInputElement>) => {
    const {
      currentTarget: { value },
    } = event;
    setHours(+value);  // String을 Number로 변환
  };
  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;

 

반응형

'Web-Frontend > React.js' 카테고리의 다른 글

[React.js] react-beautiful-dnd  (0) 2023.06.15
[React.js] React에서 Font Awesome 사용하기  (0) 2023.06.03
[React.js] React Hook Form  (0) 2023.04.05
[React.js] Recoil - atom  (0) 2023.03.28
[React.js] React Query  (0) 2023.03.22