리코일(Recoil)은 왜 만든 건데?

개발자재영·2021년 1월 17일
100

목록 보기
3/3
post-thumbnail

리코일 개념을 정리하는 포스팅이다.


화면 변경을 위해 필요한 상태 🔈 🔇 🔉 🔊


위 화면은 클릭일 때에는 배경색을 파란색으로 변경하고 검정색 바를 오른쪽으로 이동시키는 기능을 보여준다.

배경색 파란색으로 변경하기

클릭되지 않았을 때의 배경색을 #111으로 지정하는 스타일을 작성하고 클릭되었을 때 배경색을 #20b7ff으로 지정하는 스타일를 하나 더 작성한다.

검정색 바 오른쪽으로 이동 시키기

클릭되지 않았을 때에는 left:0으로 왼쪽에 위치하도록 스타일을 지정하고 클릭되었을 때에는 left:40px로 오른쪽으로 40px 이동하도록 스타일를 하나 더 작성한다.

웹에서는 화면에 보여주고 싶은 상황에 따라 여러 스타일시트를 작성하고 그 상황에 맞는 상태를 만들어 상태값을 이용해서 상황에 맞는 스타일시트가 적용되도록 한다.

즉, 여러 상황에 맞는 다양한 화면을 보여주기 위해서 상태가 필요하다.

리액트의 화면 변경 ⚛️

리액트(React)는 왜 쓰는 건데⁉
-리액트에 대한 자세한 내용은 이 링크를 참고해주세요.

이미지 : Redux가 필요하다는 것을 언제 알 수 있나요?

리액트에서는 가상돔(Virtual DOM)을 이용해 변경된 상태를 파악해서 이전과 다르게 변경된 상태를 화면에서 다시 그려준다.(다시 랜더링한다)
변경된 곳만 다시 화면을 그려주면 화면 전체가 깜빡이는 것을 없애주어서 사용자 경험을 향상 시켜준다. 또 화면 전체를 다시 그릴 때보다 더 적은 브라우저의 자원을 활용하기 때문에 빠르고 쾌적한 사용자 경험을 제공한다.

프론트엔드의 상태 관리 🔔 🔕

리덕스(Redux)는 왜 쓰는 건데⁉
-리덕스에 대한 자세한 내용은 이 링크를 참고해주세요.

리액트의 상태를 이용해 화면의 변화를 줄 수 있지만 프론트엔드의 프로젝트가 점점 커지면서 그 상태가 너무 많아졌다. 그래서 상태를 체계적으로 관리해야 하는 필요성이 대두되었다.

그래서 리덕스가 탄생하였고 대부분의 개발자들이 리액트를 사용하면서 상태관리를 별도의 라이브러리를 이용해 관리하기 시작했다.

위의 그래프는 stateofjs의 2020년 조사 중에 Data Layer Usage 항목이다. 상태 관리를 위해서 많은 라이브러리를 사용 중이고 그 중에서 Redux는 많은 비중을 차지하고 있다.

이미지 : Redux가 필요하다는 것을 언제 알 수 있나요?
리덕스를 간단하게 설명하면 위의 그림과 같다. 상태가 변경되면 액션을 통해서 리듀서에 전달되고 리듀서에서 상태를 변경해 스토어에 저장된다. 스토어에서 상태가 변경되면 해당 상태를 사용(구독)하고 있는 컴포넌트에 변경된 상태를 전달해준다.

리코일의 탄생 동기 🙌🏻

리덕스에 대한 불만 🤦🏻‍♀️ 🤷🏻‍♀️



위의 첫번째 그림은 상태 관리 라이브러리의 만족도에 대한 조사결과이고, 두 번째 그림은 이후 3년 안에 사라질 것으로 예상되는 기술에 대한 질문의 결과이다.
리덕스의 만족도는 급격하게 떨어졌고 3년 이후 사라질 기술 1위로 리덕스가 꼽혔다.

리덕스의 단방향의 흐름은 상태를 디버깅하게 쉽게 해주지만 action, reducer, selector, store를 초기에 세팅하는 것은 엄청나게 번거로운 일이고 많은 코드를 추가하도록 강제한다. Redux Saga 이후 redux-toolkit이라는 라이브러리가 나와서 코드를 줄여주고 간단해지긴 했지만 그래도 초기에 세팅은 여전히 번거롭고 리액트와의 궁합은 만족스럽지 못하다.

리코일은 무엇인가? 👨🏼‍💻

A state management library for React

리코일을 설명하는 리코일 팀의 표현이다.
리액트를 위한 상태 관리 라이브러리

We want to improve this while keeping both the API and the semantics and behavior as Reactish as possible.

Recoil은 API, 의미, 동작을 최대한 리액트스럽게 유지하며 이를 개선하고자 한다.

페이스북에서 만든 리액트에서는 리덕스,Mobx처럼 상태 관리를 도와주는 기능이 없었다. Context API가 있긴 하지만 페이스북에서는 Context API를 이용해 상태를 관리하는 방식은 어렵다고 판단했다.

개인적인 요약으로는 new context가 (locale/theme와 같은) 낮은 빈도의 업데이트에서는 사용될 준비가 되어 있다는 것입니다. 이전 context가 사용 된 것과 동일한 방식으로 사용하는 것도 좋습니다. 즉 정적 값의 경우 구독을 통해 업데이트를 전파합니다. 하지만 모든 Flux와 비슷한 상태 관리의 대체물로 사용할 준비가 되어 있지는 않았습니다.



Context API를 사용해서 상태 관리를 하면 부분적인 상태 변경이 어려워진다. 별도의 Provider를 이용해 랜더링을 제어할려고 해도 자식 요소들 전체가 다시 랜더링해야 하고 의도치 않은 커플링이 생기는 문제가 생긴다.

반면 Redux와 Mobx의 기능적인 문제는 없다. 하지만 이 상태 관리 라이브러리들은 리액트의 내부 라이브러리가 아니기 때문에 리액트의 가상돔의 내부 로직과는 별개로 동작한다. 그러니까 Redux의 store은 리액트의 상태와는 별개의 것이기 때문에 우리는 수많은 코드를 통해서 리액트의 상태와 리덕스의 상태를 일치시키는 작업을 해야 했다. 하지만 리코일은 다르다. hook처럼 리액트의 상태를 간단하게 변경하고 이용 가능하다.

Recoil 시작하기 🔥

Atom ⚙️


Atom은 상태이다. 리액트의 state,props 와 비슷하지만 리덕스의 store의 상태들처럼 구독할 수 있고 Atom의 상태가 변경되면 구독하고 있는 컴포너트들의 다시 랜더링되면서 변경된 Atom의 상태를 공유한다.

Atom은 고유한 키값과 기본값을 가진다. 고유한 키값을 이용해서 필요한 컴포넌트에서 Atom를 사용할 수 있고 기본값은 초기값이 된다.

useRecoilState 📥 📤


useRecoilState은 hook의 useState와 사용하는 방식이 동일하다. 배열 첫번째 요소에 상태의 값이 들어가고 두번째 요소에 상태를 변경할 수 있는 함수가 들어간다. 차이점은 이 변경된 상태가 자동으로 전역으로 상태가 공유된다는 것이다. 구독이나 연결과 같은 작업은 필요없다. useRecoilState을 사용한 Atom의 상태는 이 상태를 사용하고 있는 다른 컴포넌트와 자동으로 공유된다.

useRecoilValue 📮


useRecoilValue는 상태를 변경하는 함수없이 Atom 값만 받는다.

selector 🔀



여러 상태를 이용해 값을 표현할 때가 있다. 이러한 상황에서는 각각의 상태가 변경될 때, 이 값 또한 즉각적으로 변경되어야 한다. selector는 순수함수로서 Atom이나 또 다른 selector를 이용해서 새로운 데이터를 전달해줄 수 있다. selector를 이용하면 연관된 Atomselector가 변경되면 그 따른 변경된 값을 즉시 받을 수 있고 이 selector를 사용하는 컴포넌트도 다시 랜더링된다. selector에서는 async를 이용해 비동기 작업 또한 가능하다. 서버에서 api로 데이터를 불러오는 것도 가능하다.


selector 또한 고유한 키값을 갖는다. get에는 반환 값을 만들어주면 된다. 위에 예시에는 cartState, shippingState를 이용해서 최종 가격을 연산하는 로직을 만들었다.

사용할 컴포넌트에서는 useRecoilValue를 이용해서 get에서 리턴되는 값을 받으면 된다. 아직까지는 selectoruseRecoilState와 함께 사용할 수 없다.selector의 값은 읽기전용으로만 사용 가능하다.(추후에 업데이트 될지도?)

리코일로 작업한 프로젝트


cartState,shippingState,inventoryState
카트, 배송지, 창고재고를 나타내는 상태를 만들었다.
inventoryState는 서버에서 불러오는 값으로 음료의 종류를 나타낸다.
음료 이름, 가격, 카테고리, 가격 등의 정보를 담은 atom이다.
cartState는 사용자가 ADD 버튼을 이용해 장바구니에 담을 경우 담기는 데이터이다.
shippingState는 배송지 정보로 SHIPPING 영역에서 변경 가능한 데이터이다.
이 세가지 상태가 DRINKS, CART, SHIPPING, TOTALS 화면 영역에 각각 변화를 주고 있다. 각 영역은 각각의 컴포넌트로 분리해두었다.

리코일 스타벅스 카트

Recoil 요약

  • 리코일은 atom이라는 상태를 store 없이 전역으로 관리할 수 있다.
  • atom은 구독, 옵저버와 같은 개념을 생각할 필요없이 hook을 사용하듯이 사용하면 된다.
  • hook를 사용했던 개발자라면 쉽게 사용할 수 있다.
  • selector를 이용하면 리듀서 없이 복잡한 연산도 간단하게 할 수 있다.

Recoil 가치

  • 아직 정식으로 릴리즈된 라이브러리가 아니다.
  • 페이스북에서 만든 리액트를 위한 상태 관리 라이브러리이기 때문에 만약에 정식 릴리즈된다면 리덕스와 mobx는 더 이상 사용할 필요가 없을 것 같다.
  • 리코일을 사용하면 외부 라이브러리 없이 리액트만 사용한다는 느낌이 든다. hook이 전역으로 확장되었다는 느낌이어서 조금 더 리액트스러웠다.
  • 정식 릴리즈된다면 꼭 공부해볼 가치가 있다. 하지만 아직은 모르겠다.
profile
프론트엔드 개발자입니다.

21개의 댓글

comment-user-thumbnail
2021년 1월 17일

마침 Recoil을 공부하고 있었는데 참고가 됐습니다! 좋은 글 감사합니다.

1개의 답글
comment-user-thumbnail
2021년 1월 18일

유익한 글 잘 읽었습니다.

1개의 답글
comment-user-thumbnail
2021년 1월 22일

좋은 글 감사합니다!

1개의 답글
comment-user-thumbnail
2021년 1월 27일

유익한 글 잘 읽었습니다!

1개의 답글
comment-user-thumbnail
2021년 1월 30일

감사합니다 정리에 많은 도움이 됬습니다!

1개의 답글
comment-user-thumbnail
2021년 1월 30일

와우, React/ Redux 상태 변경 gif는 직접 만드신건가요?

1개의 답글
comment-user-thumbnail
2021년 2월 3일

좋은 내용이네요 잘 읽었습니다!

1개의 답글
comment-user-thumbnail
2021년 2월 3일

정말 쏙쏙 들어오는 정리네요,, 감사합니다!!

1개의 답글
comment-user-thumbnail
2021년 2월 7일

Recoil 관련 글을 몇개 봤었는데, 제가 본 글중 가장 확실하게 이해되네요!
정식 릴리즈가 정말 기대되는군요.

1개의 답글
comment-user-thumbnail
2021년 3월 16일

좋은 글 감사합니다.

답글 달기
comment-user-thumbnail
2021년 4월 26일

잘 읽고 갑니다!

답글 달기