[React] Recoil selector의 set property

sjoleee·2022년 8월 12일
0

지난번에 Recoil에서 selector의 get 프로퍼티에 대해 알아보았다.
selector은, 특정 state의 출력값을 조정할 수 있는... 그런 기능이라고 생각했다.
get으로 state를 가져와서 어떻게 출력할지 조건을 걸고, 해당 selector을 사용했다.
그러니까... 수정은 안되는 줄 알았는데, set을 사용하면 된다고 한다.
간단한 예시로 set에 대해 알아보았다.

내가 만들고 싶은 것은 cm과 inch를 변환해주는 프로그램이다.
cm과 inch를 입력할 수 있는 input을 두개 만들고, cm input에 값을 넣으면 inch input에 변환된 값이 나온다. 반대도 마찬가지.

만들어 보도록 하자.

//CmToInch.tsx

import { useRecoilState, useRecoilValue } from "recoil";
import { cmState } from "./atom";

function CmToInch() {
  const [cm, setCm] = useRecoilState(cmState);
  const inch = useRecoilValue(inchSelector);
  //출력값이 조절된 selector를 불러와서 inch input에 사용했다.
 
  const onCmChange = (event: React.FormEvent<HTMLInputElement>) => {
    const {
      currentTarget: { value },
    } = event;
    setCm(+value); //value가 string인데, number로 변환해주는 꿀팁
  };

  return (
    <>
      <input onChange={onCmChange} value={cm} placeholder="CM" />
      <input value={inch} placeholder="Inch" />
    </>
//2개의 input을 만들고 cm를 입력하면 다른 input에 inch로 변환된 값이 표시되게 구현했다.
  );
}
export default CmToInch;
//atom.ts

import { atom, selector } from "recoil";

export const cmState = atom<number>({
  key: "cm",
  default: 0,
});

export const inchSelector = selector<number>({
  key: "inch",
  get: ({ get }) => {
    const cm = get(cmState);
    return cm / 2.54;
  }, // get을 사용해서 cmState에 2.54를 나눈 값을 출력하게 만들었다.
});


이렇게 cm을 입력하면 inch로 변환해주는건 완성!
현재 inch input은 단순히 cmState를 2.54로 나눈 값을 출력해줄 뿐인데, set으로 inch input에 입력한 값에 2.54를 곱한 값을 cmState에다 넣어주면 되겠다!

//CmToInch.tsx

import { useRecoilState } from "recoil";
import { cmState, inchSelector } from "./atom";

function CmToInch() {
  const [cm, setCm] = useRecoilState(cmState);
  const [inch, setInch] = useRecoilState(inchSelector);
  //selector도 set 함수를 만들어준다.

  const onCmChange = (event: React.FormEvent<HTMLInputElement>) => {
    const {
      currentTarget: { value },
    } = event;
    setCm(+value);
    console.log(cm);
  };

  const onInchChange = (event: React.FormEvent<HTMLInputElement>) => {
    const {
      currentTarget: { value },
    } = event;
    setInch(+value);
  }; //onCmChange와 동일하다!

  return (
    <>
      <input onChange={onCmChange} value={cm} placeholder="CM" />
      <input onChange={onInchChange} value={inch} placeholder="Inch" />
    </>
  );
}
export default CmToInch;
//atom.ts

export const inchSelector = selector<number>({
  key: "inch",
  get: ({ get }) => {
    const cm = get(cmState);
    return cm / 2.54;
  },
  set: ({ set }, newValue) => {
    set(cmState, Number(newValue) * 2.54);
  },//이게바로 set!
});

이렇게, input은 동일하게 onChange함수와 연결해주고 selector에서 설정해주면 된다.
set은 option과 newValue를 갖는데, option은 set을 갖고있다. 구조분해로 {set}으로 표현해주었고, 이 set은 두개의 매개변수를 갖는데, 첫번째가 변경하고자 하는 state, 두번째가 변경하고자 하는 값이다.
newValue는 우리가 보내는 새로운 값이다. 이걸 활용해서 input에 입력한 값을 받아와서 2.54를 곱하고 그걸 cmState에 넣어주는 것이다.

아직 좀 익숙하지 않긴 한데, trello를 따라 만들면서 계속 활용해볼 예정이다.

profile
상조의 개발일지

0개의 댓글