안녕하세요! 오늘은 Recoil을 사용해 리액트 애플리케이션에서 상태 관리를 했던 경험을 공유하려고 합니다. 결합도에 대해 생각해보면, 자료 결합도, 스탬프 결합도, 제어 결합도 등 다양한 결합도들이 있죠. 특히 전역 변수는 외부 결합도로, 뭔가 '좋아 보이지 않는' 그런 느낌이 있어요. 그럼에도 불구하고 리액트에서 상태 관리는 전역 상태가 될 필요는 없지만, Recoil 같은 라이브러리를 사용할 때는 대부분 전역 상태 관리로 하게 됩니다.
그렇다면 왜 수많은 상태 관리 방법 중에서 우리는 Recoil을 선택했을까요?
Recoil 선택의 이유
- 너무 쉬웠어요: Recoil이 처음 나왔을 때 그 사용 방법이 정말 쉬웠습니다. 설정도 간단했고, 상태 관리도 꽤 편리했죠. 그래서 처음 접한 우리 팀도 "이거 좋다, 사용해보자!"라고 쉽게 결정할 수 있었습니다.
- 새로운 건 써봐야 제맛: 솔직히 말해서, 새로운 게 나오면 써봐야 하는 그 마음이 가장 컸던 것 같아요. "좋은지 안 좋은지는 나중에 보고, 지금은 일단 써보자!"라는 마음으로 Recoil을 선택하게 되었죠.
그럼 다른 상태 관리 방법보다 정말 좋은 건지, 아니면 그냥 아무 생각 없이 쓴 것인지 궁금하시죠? 각 상태 관리 방식에는 장단점이 있습니다
상태 관리 | 장점 | 단점 |
Local State | 간단하고 직관적, 상태 관리가 독립적 | Prop Drilling 문제 발생 가능 |
Context API | 전역 상태 관리 가능, 리액트 내장 기능 사용 | 성능 문제, 여러 컨텍스트가 복잡해질 수 있음 |
Recoil | 쉬운 전역 상태 관리, 간단한 상태 공유 | 추가 학습 필요, 자료나 생태계 제한적 |
Redux | 명확한 데이터 흐름, 미들웨어를 통한 비동기 처리 가능 | 많은 보일러플레이트, 코드 복잡도 증가 |
MobX | 자동 반응형 업데이트, 간단한 사용 | 디버깅 어려움, 생태계 부족 |
Zustand | 가볍고 간단한 설정, 리액트 방식과 유사 | 기능 제한, 대규모 프로젝트에 비적합 |
각 방식마다 장단점이 있지만, 쉽고 간단하다는 점이 우리 팀에 가장 큰 매력이었습니다. 무엇보다 빠르게 작업을 해야 하는 상황에서 Recoil은 정말 좋은 선택이었죠. 물론 Local State도 함께 사용하면서 더욱 강력한 상태 관리가 가능했습니다.
Prop Drilling과 Recoil의 등장
그럼 왜 Recoil을 사용하게 되었을까요? 리액트를 사용해 보신 분들이라면 모두 prop으로 값을 전달하는 것을 아실 겁니다. 컴포넌트를 재사용하기 위해서 컴포넌트를 잘게 쪼개고, 그러다 보면 props를 계속 전달하는 것이 필요해지죠. 그리고 그 값이 필요하지 않은 컴포넌트까지도 props를 전달해야 하는 상황이 발생합니다. 이게 바로 유명한 Prop Drilling 문제죠. 😂
한 컴포넌트에서 자식 컴포넌트로, 또 그 아래로, 그 아래로… 이 과정을 반복하다 보면 코드가 끝도 없이 복잡해집니다. 한 번 변경하려고 하면 값을 여기저기서 리턴하고 또 리턴해야 하고, 글로 쓰기만 해도 머리가 아파옵니다. 이런 Prop Drilling 현상은 코드를 유지보수하기 어렵게 만들고, 개발자들에게 큰 스트레스를 주죠.
이때 등장한 것이 바로 Recoil입니다. Recoil을 사용하면 상태를 전역으로 관리할 수 있어 중간 컴포넌트가 불필요하게 값을 전달할 필요가 없고, 사용하지 않는 컴포넌트도 props를 물고 있을 이유가 없습니다. 전역 상태를 통해 필요한 컴포넌트에서만 값을 구독하고 사용하면 되는 거죠.
이렇게 상태를 관리하니 작업의 효율성이 높아졌고, prop의 스트레스에서 해방될 수 있었습니다. 개발자라면 다들 아시겠지만, prop 때문에 발생하는 문제에서 벗어나는 건 정말 큰 해방감이에요. 덕분에 우리는 더 빠르고 깔끔하게 작업할 수 있었습니다.
Recoil 간단 예시
Recoil을 이해하기 위해 간단한 예시를 살펴보겠습니다. 다음은 리액트 애플리케이션에서 Recoil을 사용해 카운터 상태를 관리하는 코드입니다.
import React from 'react';
import { RecoilRoot, atom, useRecoilState } from 'recoil';
// 전역 상태 정의 (atom)
const counterState = atom({
key: 'counterState', // 각 atom은 고유한 키를 가져야 합니다.
default: 0, // 초기값
});
function Counter() {
const [count, setCount] = useRecoilState(counterState);
return (
<div>
<h1>Counter: {count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
<button onClick={() => setCount(count - 1)}>Decrement</button>
</div>
);
}
function App() {
return (
<RecoilRoot>
<Counter />
</RecoilRoot>
);
}
export default App;
이 예시에서는 counterState라는 **전역 상태(atom)**를 정의하고, 이를 useRecoilState 훅을 통해 사용하고 있습니다. RecoilRoot로 애플리케이션을 감싸 전역 상태가 모든 하위 컴포넌트에서 접근 가능하도록 설정합니다. 카운터 컴포넌트는 counterState를 구독하고, 버튼을 통해 상태를 업데이트할 수 있습니다.
마무리하며
Recoil은 쉽고, 간단하고, 무엇보다 빠른 작업이 필요했던 저희 팀의 요구를 충족시켜 준 도구였습니다. 물론 모든 상황에서 Recoil이 정답은 아닐 수 있지만, 저희 팀이 겪었던 문제를 해결하고 효율적으로 작업을 마칠 수 있도록 도와준 훌륭한 도구였다고 생각합니다.
다른 상태 관리 도구들도 각자의 장점이 있지만, 여러분의 프로젝트 상황에 맞는 도구를 선택하는 것이 중요합니다. 저희처럼 새로운 것에 도전하고 경험해 보는 것도 좋은 방법일 수 있어요. 😊
여러분도 Prop Drilling 문제로 고생하고 계신다면, Recoil 한번 써보시는 건 어떨까요? 감사합니다!
'개발 > 개발 필기' 카테고리의 다른 글
tmux 사용 (0) | 2024.12.04 |
---|---|
마케팅 회사에서 개발자로 일하며 얻은 성장과 경험 (4) | 2024.12.03 |
JavaScript에 재미있는 현상 (0) | 2024.12.02 |
효율적인 배열 비교: Set을 사용해 코드 개선하기 처음에는 조금 복잡하게 코드를 작성했지만, 개선을 통해 훨씬 깔끔하고 효율적인 코드로 만들 수 있었어요. 이 과정을 함께 살펴볼까요? (2) | 2024.11.28 |
프론트엔트 지식 GPT질문 (5) | 2024.11.26 |