지난번에 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를 따라 만들면서 계속 활용해볼 예정이다.