1. 왕위 부재
한동안 기본적인
context
, prop
, state
가 유일한 상태관리 방법이었음.- 페이스북에서
Flux 아키텍처
를 발표함. 근데 공개된 코드는 없었음.
- 페이스북에서
디스패처
만 공개하고 나머지 구현에 대한 코드는 없음.
3. Flux 구현체의 등장
- 2015년
Redux
,MobX
등 Flux 아키텍처를 구현한 라이브러리들이 공개되기 시작함.
- 이들은 리액트에 종속된 것이 아닌 독립된 라이브러리임.
- 여러 라이브러리들이 더 나왔지만
Redux
와MobX
가 양대산맥을 지켜왔음. (여러가지 미들웨어들도 한몫함)
4. Context API
test1, setTest1 test2, setTest2 test3, setTest3
사실 전역상태관리도 되고, 리액트도 잘 지원하는
Context API
라는 것이 있긴 했음.하지만, 변화한 상태와 관련된 컴포넌트만 re-render되는 것이 아니라, context 자체를 구독하고 context 내의 어떤 상태라도 변화하면 해당 context를 구독한 모든 컴포넌트들이 re-render된다는 이슈가 있다.
따라서
- 상태가 많다면 불필요한 re-render를 줄이고자, 데이터마다 Context를 만들고 Provider를 제공해서 씀.
⇒ 너무 많은 Provider가 중첩됨...ㅋㅋㅋㅋ (번거롭고, 코드 보기도 안좋아..!)
- 상태가 적어서 re-render 되어도 부담이 적은 것들만 묶어서 관리


따라서 별도의 라이브러리의 도움 없이 Context API 만으로 상태관리를 하기에는 무리가 있었다.
(
constate
와 같은 서드파티 라이브러리가 이것을 편하게 도와주긴 함. )5. Recoil 탄생
- 페이스북이 2020.5월에 React EU에서 발표함
- React를 "더 잘" 지원할 목적으로 작성
- 다른 상태관리 라이브러리는 범용 라이브러리인 반면에,
Recoil
은 React를 기반으로 작성된 React전용 라이브러리임.
데이터 플로우
Recoil의 데이터 흐름은
Data-flow 그래프
로 표현됨데이터 플로우 그래프는 계산이나 데이터의 흐름을
노드
와 엣지
로 표현하는 그래프인데, 머신러닝 해봤으면 들어봤을 것.Recoil에서는
Atom
이 Selector
를 따라서 흘러서 React 컴포넌트로 흘러감.
아톰(Atom)
- 하나의 상태 데이터
key
와default
value만 설정하면 돼서 굉장히 단순함.
셀렉터(selector)
두가지 의미를 가짐
- 아톰에서 파생 된 데이터 조각
- 데이터를 반환하는 순수함수

[실습] 간단한 카운터 예시
redux와는 어떻게 다른거지??
recoil을 통해 보일러플레이트 코드가 확 줄어서 훨씬 깔끔하고 간단하게 코드를 작성할 수 있다.
selector와 dispatch보다, 그냥 useState 훅 처럼 사용하기 때문에 코드가 좀 더 직관적임.
- Recoil 버전 : https://codesandbox.io/s/recoil-counter-8y3cn
1. App.jsx 파일에 <RecoilRoot>를 추가한다.
RecoilRoot
하위에 있는 모든 recoil 데이터의 루트가 된다.
내부적으로는 react의 context api를 사용하고 있고, store를 선언해서 context에 내려주는 역할을 함
리덕스를 쓸 때는 직접 store를 만들어야하는데, recoil에서는 RecoilRoot만 선언하면 알아서 스토어 만들어짐.
RecoilRoot는 중첩해서 쓸 수도 있음.
중첩할 경우 atoms와 selectors는 가장 가까운 RecoilRoot에 선언된 store를 사용함
어쨋든 데이텉를 저장하고 여러 컴포넌트에서 공유하려면 RecoilRoot로 감싸줘야한다는 점만 기억하자.
import React from 'react'; import { RecoilRoot } from 'recoil'; import './styles.css'; export default function App() { return ( <div className="App"> <h1>Hello CodeSandbox</h1> <h2>Start editing to see some magic happen!</h2> <RecoilRoot></RecoilRoot> </div> ); }
2. Counter 컴포넌트 작성
- Counter.jsx 파일을 만들고, 빈 Counter 컴포넌트를 작성함
- App.jsx파일에 Counter 컴포넌트를 추가함.

- Counter.jsx에 count 상태
아톰
을 선언함
( 카운터라서 0으로 뒀지만, default 값에는 객체, 리스트 같은 복잡한 것들도 전달 가능 )
- count 아톰을 사용하기 위해
useRecoilState
훅을 호출함.
- 화면에 카운터를 표시하고 카운터를 증가/감소하는 버튼을 추가함

[실습] 예제2 - 셀렉터 사용하기 (짝인지 홀인지 알려주는 것)
사용할 상태 아톰의 key와 / get, set, reset 을 이용해서 파생 데이터를 만들어 반환할 수 있음.


[실습] 예제3. 서버 API 연동
비동기 데이터 처리는 recoil의 단순함의 장점이 가장 잘 보이는 부분이라고 생각함.



가져오기 전까지에 대한 처리가 없으므로, 에러가 나는 것이 정상임.

suspense는 컴포넌트를 완전히 렌더링할 수 있기까지 렌더링을 멈춰두는 기능임.
recoil의 목적 중에 react를 좀 더 잘 구현하려고 하는 부분이 있었음.
suspense는 향후에 도입될 동시성 모드 기능의 일부임.

fallback에는 기다리는 동안 보여줄 컴포넌트를 전달하면 됨.
동기식 데이터와 비동기식 데이터를 크게 다르지 않은 형태로 다룰 수 있다는 장점도 있음.

atom과 selector는 같은 hook을 사용하지만, loadable은 전용 api를 써야함.
use...loadable 관련 훅들이 몇가지 있음.

suspense는 error 처리를 하려면 try-catch를 별도로 해줘야하는데, lodable 훅을 이용하면
로딩
성공
실패
를 전부 커버할 수 있음.redux에서는 비동기 처리를 위해 별도의 서드파티 라이브러리가 필요했고, mobX도 로딩상태를 표현하기 위해서 사용자가 별도로 상태처리를 해줘야하는 번거로움이 있었음.

추천!!! (이게 recoil의 최종 template이 될듯)




검색어별로 자동으로 결과를 캐시해두므로, 별도의 캐싱 작업을 할 필요가 없다.
그 이유는 검색어를 atom에서 가져오기 때문에 가능함.
아래에서 좀 더 자세히 살펴보자.

selectro안에서 사용한 atom에는 자동으로 의존성이 걸림
- 의존된 아톰의 상태 값이 변경될 때마다 자동으로 파생된 selector의 값도 변하게됨.
- 의존성 걸린 값이 모두 같으면 동일한 결과를 반환함
- 내부의 코드를 보면 반환값을 memoize하고있음.
한번 검색한 결과는 서버에서 가져오지 않고 캐시에서 가져오므로 더 빠르게 가능.

훅으로만 지원되므로 클래스형으로는 작성할 수 없다는 단점이 있긴하지만, HOC 패턴을 통해 충분히 극복 가능