상태관리 라이브러리, 뭘 쓸까?

이정민 Lee Jeong Min·2021년 8월 20일
45

Web

목록 보기
4/4
post-thumbnail

상태관리를 왜 해야 하나요?

다들 리액트 많이 사용하시나요?
프론트 개발자라면 한번쯤은 사용해보셨을 라이브러리라고 할 만큼 인기가 많은 라이브러리인데요,

리액트가 뷰나 앵귤러와 비교했을 때 가장 큰 차이점은 단방향 바인딩이 아닐까 싶습니다.
리액트는 단방향 바인딩을 지원하기 때문에 부모에서 자식으로만 stateprops로 전달할 수 있고, 자식의 props를 부모에게 직접 전달할 수는 없습니다.

자식에서 부모의 상태를 바꾸려면 해당 상태를 컨트롤하는 함수를 props로 넘겨주어야 합니다.

하지만 이것이 반복되다 보면 엄청난 props drilling이 발생하게 된다는 문제가 있습니다. 또한 프로젝트의 규모가 커질수록 props의 뎁스가 증가하게 되고, 이는 불필요한 리렌더링을 유발할 수도 있습니다.

그럼 state/props로 모든 상태를 관리하는 것은 별로인가요?

그렇지는 않다고 생각합니다! 컴포넌트의 재활용성이라든가, 의존성 분리 등의 측면에서 props는 잘 다루면 좋은 도구가 될 수 있습니다. 다만 컴포넌트의 역할에 치우쳐진 데이터가 아닌, 프로젝트 전반적으로 사용되는 데이터의 경우 글로벌로 두고 공유하되, 그에 대한 부가적인 상태들을 state/props로 처리하면 더 효율적이지 않을까 생각합니다 🙃

그렇다면 뭘 써야 하나요?

상태관리 라이브러리, 종류가 참 다양합니다!
Redux, MobX, Recoil 등등 많은 도구들이 존재하는데요,
각 라이브러리마다 장단점이 있고 프로젝트의 특성에 맞게 골라 쓰면 좋을 것 같습니다.

Redux

리덕스가 나오기 이전, 리액트를 포함한 대부분의 프로젝트는 MVC 아키텍처가 많이 사용되었습니다. 컨트롤러가 여러 모델을 제어하고, 모델과 뷰가 서로를 바라보는 구조로, 모델과 뷰가 양방향으로 영향을 미치기 때문에 프로젝트의 규모가 커지고 상태가 많아질수록 관리가 어려워집니다.

그렇게 페이스북이 내놓은 새로운 아키텍처가 Flux 아키덱처입니다. 데이터의 흐름이 단방형으로 흐르는 구조입니다.

이러한 Flux 아키텍처를 가져가는 라이브러리로 대표적인 것이 리덕스입니다. action, reducer, selector, store를 세팅하는 보일러플레이트 코드는 분명 유지보수에 큰 장점을 가지고 있기도 하지만, 상태의 개수가 적더라도 보일러플레이트 코드가 크기 때문에 불편함이 존재합니다.

리덕스와 같은 Flux 아키텍처의 라이브러리의 경우, store에 모든 상태를 저장하는 중앙집중방식입니다. 이 store는 외부 요소이기 때문에 리액트의 내부 스케줄러에 접근할 수가 없습니다. 또한 리덕스의 경우 비동기 데이터 처리를 하기 위해서는 사가와 같은 별도의 라이브러리를 추가적으로 사용해야 합니다.

리덕스는 데이터 관리에 대해 상당히 보수적인 접근방식을 취하고 있는데요, 이는 높은 러닝커브와 큰 보일러플레이트 코드를 낳았지만 확장 및 디버깅에 있어서는 엄청난 강점을 가지고 있습니다.

  • 리덕스는 오직 하나의 스토어만 가지며, 하나의 객체 트리를 가지기 때문에 디버깅이 용이합니다.
  • 스토어 내부의 상태는 action 객체에 의해서만 변경될 수 있습니다. 모든 상태 변화들이 하나의 store에 집중되어 있고 오직 단방향으로 일어나기 때문에 항상 예측 가능한 결과를 낳게 됩니다.
  • 리듀서는 순수함수로써 상태를 변경하는 것이 아닌 새로운 상태를 반환하게 됩니다.

MobX

MobX 또한 좋은 라이브러리입니다! 다만 사용률이 리덕스에 비해 현저히 딸릴 뿐, 러닝커브도 적당하고 유용한 라이브러리인 것 같습니다 😀

MobX의 경우 리덕스와 달리 불변성에는 신경써주지 않아도 될 정도로 규칙만 잘 신경써준다면 최적화가 잘 됩니다.

MobX는 여러 면에서 리덕스보다는 다루기가 쉬운 라이브러리인데요, 그렇기에 단점들도 분명 존재합니다.

  • MobX의 경우 리덕스와 달리 store가 여러 개가 될 수 있는데요, 이는 분리가 용이해 편리할 수도 있는 반면 상태 변경시 다수의 스토어가 영향을 받을 수 있습니다.

  • 리덕스와 다르게 스토어의 데이터를 액션의 발행없이 업데이트할 수 있는데요, 이는 구현은 쉽고 용이하지만 테스트나 유지보수의 측면에서는 문제를 일으킬 수도 있습니다.

그렇기에 장기적인 프로젝트, 유지보수 및 확장성을 고려해야 하는 프로젝트의 경우에는 MobX는 좋지 않은 선택일 수 있습니다.

하지만 리덕스보다 러닝커브가 낮고 보일러플레이트 코드의 양 또한 적기 때문에 프로젝트의 규모가 크지 않다면 MobX를 사용하는 것은 좋은 해결책이 되리라 생각합니다 🤓

Recoil

페이스북은 꽤 최근 리코일이라는 새로운 라이브러리를 내놓았습니다. 그리고 리코일은 스스로를 '리액트를 위한 상태관리 라이브러리'라고 소개하고 있습니다.

리코일은 아톰과 셀렉터로 이루어져 있습니다.
아톰은 상태의 단위로, 유니크한 키값으로 구분됩니다. 해당 아톰을 구독하고 있으면 해당 컴포넌트들만 선택적으로 리렌더링됩니다.

아톰의 상태변화는 순수함수를 통해 일어나는데, 이를 셀렉터라고 합니다. 셀렉터에서는 비동기처리 뿐만 아니라 데이터 캐싱 기능도 제공하기 때문에 비동기 데이터를 다루기에도 용이합니다.

이러한 접근을 통해 리코일은 다음과 같은 특징을 가질 수 있는데요,

  • 보일러플레이트가 없기 때문에 리액트 지역 상태로서 단순한 get/set 인터페이스로 상태를 공유할 수 있습니다.
  • 동시성 모드와 양립할 수 있는 가능성이 있습니다.
  • 상태를 분산적으로 둘 수 있기 때문에 코드 스플리팅이 가능합니다.

하지만 아직 버전이 낮기 때문에 안정성의 측면에서는 좋지 못할 수도 있습니다. 또한 DevTool이 아직 미흡하기 때문에 큰 규모의 프로젝트에서는 도입하기가 힘들 것으로 보입니다.

Context API

Context API는 리액트가 자체적으로 가지고 있습니다. 정적인 데이터 위주로 처리하거나 업데이트가 빈번하지 않을 때 적합합니다.

빈번하고 복잡한 업데이트를 처리 시에는 비효율적인데요,
Context API의 경우 Provider-Consumer 구조로 상태를 주고 받는데, Provider 하위의 모든 ConsumerProvider 속성이 변경될 때마다 리렌더링됩니다.
useMemo를 통해 Providervalue props를 메모이제이션할 수는 있지만, 렌더링 최적화에 있어서는 여전히 아쉬운 점이 있는 것 같습니다.

만약 Context API를 사용한다면, useReducer와 함께 사용한다면 보다 좋은 코드를 작성할 수 있을 것 같습니다 😁

useSWR? react-query? apollo? 이건 뭔데?

쿼리를 통한 상태관리도 많이 사용되고 있습니다!
React Query VS SWR VS Apollo VS Client RTK-Query

저는 개인적으로 위의 라이브러리들은 정확이 상태관리 라이브러리는 아니라고 생각합니다! local state들을 관리하는 개념이라기 보다는 api콜과 관련된 비동기 상태들을 관리하는 것에 더 가깝기 때문입니다. 아폴로나 SWR을 사용하더라도 프로젝트 내부의 local state들을 관리하기 위해서는 추가적인 상태관리 라이브러리를 사용하는 경우가 많습니다 :)

보통 React QuerySWRRESTful api와 함께, ApolloGraphQL과 함께 많이 사용되곤 합니다.
저는 개인적으로 GraphQL을 자주 사용해왔기 때문에 ApolloAutomatic Refetch after Mutation기능을 유용하게 사용했던 것 같습니다 😚

개인적으로 이번에는...

최근 진행하고 있는 프로젝트에서는 react queryrecoil을 사용하여 진행해보고 있습니다!

배민문방구 사이트를 개선해보는 프로젝트로, 커머스 사이트 특성상 컴포넌트 뎁스가 깊기 보다는 컴포넌트 전환이 많았고, 따라서 props drilling이 심하지는 않다고 생각되었기 때문에 대부분의 상태들은 state/props로 관리하였습니다.

다만 페이지 간에 전달해주어야 할 데이터들 같은 경우에는 global로 다루어야할 필요가 있었기 때문에 recoil을 사용해주었고, 그 개수도 많지 않습니다!

하지만 커머스 특성상 빈번한 crud가 일어나기 때문에 그에 대해 처리해야할 비동기 데이터가 많았고, 대부분의 api fetechinguseQuery 훅을 사용하여 다루고 있습니다 😆

ET네 만물상
현재 진행하고 있는 프로젝트입니다! 상태관리 라이브러리 외에도 유닛 테스트, DDD 등의 재미있는 요소들이 많으니 들러보시는 것도 추천드립니다 🤗

profile
https://jeong-min.com/ <- 블로그 이전했습니다 :)

11개의 댓글

comment-user-thumbnail
2021년 8월 20일

엉엉 제 상태관리 1부는 언제 다 쓰죠

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

따봉드립니다

답글 달기
comment-user-thumbnail
2022년 9월 24일

글 잘 봤습니다.
클라이언트 + 서버 상태관리로 분리해서 항상 바라보고 있는데 좀 햇갈렸는데
이 글을 보고 정리가 조금 되었던 같네요
감사합니다.!

답글 달기
comment-user-thumbnail
2023년 9월 12일

So what you do not have a partner or so what if you are fed up of your partner as life always stores the next chance for you. In case you are sick of your love life or want some change in it then going for salacious Delhi escort would be a great switch on for you.
https://www.ayushikapoor.com/
https://www.hotelescortsnearme.com/
https://www.devikagupta.in/
https://www.preetkaur.in/
https://www.thedelhiescorts.in/

답글 달기
comment-user-thumbnail
2023년 9월 18일

We never concoct low class escort administrations as we put stock in offering premium administrations to our clients. We ensure that all our attractive hunks get to satisfy their dreams and wants with full energy and positive thinking. https://www.callgirlsghaziabad.com/ The most amazing aspect of having our escort administrations is their moderateness. We have the best and modest escort administrations in for our clients so they can include everything inside their spending plan. Thusly, reach out to us to enlist your escort friend now.

답글 달기
comment-user-thumbnail
2024년 1월 30일

We can make your mood by providing you sexy Indian, Russian and Uzbek call girls in Delhi.
https://makeyourmood.in/

답글 달기