# Kyte Recoil 검토
### Recoil 기본?
https://recoiljs.org/ko/
https://github.com/facebookexperimental/Recoil
Recoil 은 facebook 에서 직접 만든 `상태관리` 라이브러리 인데요.
2020년 5월에 출시하여 비교적 최신기술이며 공식 문서에 나온 것 처럼 가장 `React 와 유사한 사용성`을 보입니다.
어떤점이 React와 유사한지 알기 위해서는 Recoil에 기본개념인 먼저 **Atom**과 **Selector**에 대해 이해해야 합니다.
- Atom
리코일에서는 atom() 함수를 제공하는데요, 이함수를 통해 흔히 사용하는 `State`를 정의할 수 있습니다.
```typescript=
const kyteState = atom({
key: 'kyteState',
default: initialState,
})
```
위와 같이 kyteState를 **atom** 함수를 통해 정의하고, App의 상위에 **<RecoilRoot></RecoilRoot>** 만 담아두면, 어느 위치에서든 kyteState를 사용할 수 있습니다. ~~(정말 간단하죠?..)~~
atom 함수를 통해 여러개의 state를 생성할 수 있고, unique key 가 다르면 각각의 state를 개별적으로 관리할 수 있습니다.
특정 state가 업데이트 된다면, 해당 state를 구독하고 있는(동일한 key) 컴포넌트들이 리렌더링 됩니다.
- Selector
selector는 파생된 상태라고 소개되어 있는데요. atom으로 만들어진 state 혹은 다른 selector를 구독하여
새로운 state를 만드는 **순수함수** 입니다. (reducer 와 유사한 것 같습니다.)
```typescript=
const kyteLengthState = selector({
key: 'kyteLengthState',
get: ({get}) => {
const kyteState = get(kyteState);
return kyteState.length;
},
});
```
~~atom 과 비슷한 인터페이스를 가지고 있어서 헷갈리네요..~~
recoil에서는 selector를 통해 비동기를 처리하고, 캐싱도 지원한다고 합니다.
가장 react와 비슷하다고 느낀점은 사용처에서 state를 사용하는 방식인데요,
다음은 recoil에서 제공하는 API 중 일부입니다.
useRecoilState(), useRecoilValue(), useSetRecoilState()
```typescript=
const [state, setState] = useRecoilState(kyteState)
// useState를 쓰는 착각에 빠진것 처럼..(상태는 전역)
const readState = useRecoilValue(kyteState)
// value를 가져오기만 할때 사용
const setState = useSetRecoilState(kyteState)
// set할때만 사용
```
recoil은 이렇게 간략히 보아도 쉽게 이해할 수 있는 것 같습니다.
---
#### 장점과 단점

> npm trend 비교 (https://www.npmtrends.com/mobx-vs-react-redux-vs-recoil)
trend 에서 보이는 것처럼 아직까지 recoil은 낮은 버전이라 다른 라이브러리에 비해 많이 사용되고 있지는 않습니다.
- 장점
```
- React스러운(?) 라이브러리, 유사한 구조
- 간단한 코드 + 간단한 사용법 = 낮은 진입장벽
- 발전가능성
->
- recoil에서 비동기 데이터를 처리할때 loading 부분을 react 에서
기본적으로 제공하는 suspense 를 활용할 수 있습니다.
(suspense는 실험단계로 react 18버전 부터 사용할 수 있을 것 같습니다..)
- 공식문서에 atom effect를 보면 (https://recoiljs.org/ko/docs/guides/atom-effects)
로컬스토리지 지속성, 브라우저 URL 히스토리 지속성등 유용할 것 같은 유틸들이 있습니다.(개발중.....)
```
- 단점
```
- 낮은 버전
- 아직 1버전도 출시하지 않아(2021-11 0.5버전...) 불안정한 상태입니다..
- devtools 가 없음(개발중...)
- 복잡한 상태관리
->
상태들이 많은 의존성을 갖게 되면, 해당 상태의 업데이트에따라 많은 부분이 영향을 받기 때문에
정리된 구조로 작성되지 않으면, 예측하기 어려울 것 같습니다.
```
---
#### Recoil in Kyte
recoil을 검토하면서 kyte 프로젝트에 적용한다면, 어느부분에 할 수 있고 또 어떻게 해야할지 고민해 보았습니다.
(지극히 개인적인 생각입니다..)
- 비동기 데이터 관리
kyte 프로젝트에서 비동기데이터를 관리하는 부분은 현재 **react-query** 가 주로 담당하고 있습니다.
recoil 에서도 selector를 통해 비동기 데이터를 관리할 수 있고, 캐시도 지원하는데요.
하지만, 이미 어느정도 구조화 되어있는 ~~(개선이슈도있지만?..)~~ react-query를 대체하기에는 팀원 모두가 recoil에 높은 이해도를 가져야하고 사용성 측면에서도 장점이 보이지 않는 것 같습니다.
devtools, 에러핸들링, cache 데이터 관리등에서도 react-query를 유지하는게 훨씬 좋아보여서 이부분은 recoil에 사용할 이유를 찾지 못했습니다.
- vs redux
리덕스의 단점(?)으로 꼽히는 부분은 **많은 코드량과 높은 진입장벽**이라고 생각하는데요, typesafe-actions 같은 툴을 사용하여 많이 완화되긴 했지만, action type 정의, action 생성, reducer 생성등 간단한 작업을 할 때에도 많은 코드량을 요구합니다.
리덕스가 주로 사용되는 부분은 assistanceView 인데요.
글로벌로 동작해야 하지만, 간단한 상태를 공유하는 부분이라 recoil을 통해 충분한 대체가 가능할 것 같습니다.(앞으로의 비슷한 기능에 대해 더 간결하고 빠르게 적용할 수 있을 것 같은 기대(?)...)
하지만 개인적인 생각으로 1버전 이후에 사용하고 싶은데, 어떻게 생각하시나요?
- vs contextAPI
정확하게 파악하고 있는건 아니지만 컨텍스트API를 통해 User, Config등을 관리하는 것으로 알고 있는데요.
recoil을 통해 대체가 가능할 것 같지만 지금 이미 사용되는 부분이 너무너무 많고 얽혀있는 부분이 많아 꽤나 어려운 작업이 될 것 같습니다. Next로 migration 하면서 이부분을 수정해야 한다면 한번 고려해봐도 괜찮을 것 같습니다.
---
#### 결론
지금까지 검토한 결론은 사용하지 않는것 입니다..
이유를 정리하면 다음과 같습니다.
1. 장기적으로 보았을때 나쁘지 않지만, 부분적용을 해도 생산성, 사용성면에서 큰 차이가 없을 것 같음
2. 버전이 너무낮아 추후에 더 좋은 기능을 활용하여 안정적으로 적용하는게 좋아보임
3. 다른 작업들 (SSR적용, 라이브러리 버전업)에 비해 우선순위가 매우 낮은것 같음
어떻게 생각하시나요?