일상이 개발

React 실무 패턴 정리: 자주 사용하는 컴포넌트 설계 방식 총정리

디어노미 2025. 4. 4. 11:39
반응형

🚀 실무에서 자주 쓰는 React 패턴 정리

React로 프로젝트를 하다 보면, 단순히 동작하는 컴포넌트를 만드는 것보다 더 중요한 것이 코드의 일관성유지보수성입니다. 규모가 커질수록 "어떻게 짜야 잘 짰다고 할까?" 하는 고민이 커지게 되죠.

이번 글에서는 실제 실무에서 자주 사용하고 있는 React 개발 패턴을 정리해보았습니다.
코드 예제와 함께 소개해드릴게요!

모든 패턴은 프로젝트에 100% 무조건 적용해야 한다는 의미가 아닙니다.
상황과 맥락에 맞게 적용하는 것이 가장 중요합니다.

1. Container & Presentational Pattern

UI와 로직을 분리하는 고전적인 방식입니다. 로직을 처리하는 Container 컴포넌트와 UI만 담당하는 Presentational 컴포넌트를 분리하여 역할을 명확히 합니다.

// UserContainer.js
const UserContainer = () => {
  const { data, isLoading } = useUser();
  return ;
};

// UserList.js
const UserList = ({ users, loading }) => {
  if (loading) return
  Loading...;
  return users.map((user) =>
   {user.name}
  );
};
 
💡 TIP: UI 디자이너와 협업이 많을 경우 이 패턴이 특히 유용합니다.

2. Custom Hook 패턴

로직을 재사용 가능하게 만드는 데 가장 유용한 도구가 Custom Hook입니다. 특히 API 요청, 상태 처리, 이벤트 관리 등을 컴포넌트 밖으로 분리할 수 있습니다.

// useInput.js
export const useInput = (initialValue) => {
  const [value, setValue] = useState(initialValue);
  const onChange = (e) => setValue(e.target.value);
  return { value, onChange };
};

// 사용 예시
const Login = () => {
  const email = useInput('');
  return <input {...email} />;
};

3. Compound Component 패턴

컴포넌트 간 강한 관계가 있는 UI (예: Tabs, Accordion 등)를 구현할 때 유용한 패턴입니다. 부모 컴포넌트가 상태를 관리하고 자식 컴포넌트끼리는 context를 통해 통신합니다.

// Tabs.js
const Tabs = ({ children }) => {
  const [activeIndex, setActiveIndex] = useState(0);
  return (
    <TabContext.Provider value={{ activeIndex, setActiveIndex }}>
      <div>{children}</div>
    </TabContext.Provider>
  );
};

Tabs.Panel = ({ index, children }) => {
  const { activeIndex } = useContext(TabContext);
  return index === activeIndex ? <div>{children}</div> : null;
};

4. Props Drilling 방지: Context API 활용

컴포넌트가 깊어지면서 props를 여러 단계로 전달해야 하는 경우, Context API를 활용하면 구조를 더 깔끔하게 유지할 수 있습니다.

// ThemeContext.js
const ThemeContext = React.createContext();

export const ThemeProvider = ({ children }) => {
  const [theme, setTheme] = useState('light');
  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      {children}
    </ThemeContext.Provider>
  );
};

// 사용 예시
const Button = () => {
  const { theme } = useContext(ThemeContext);
  return <button className={theme}>Click</button>;
};

5. 상태 관리: Lifting State vs 전역 상태 관리

React는 기본적으로 상태를 부모로 끌어올려서(lifting state) 공유하게 되어 있어요. 하지만 규모가 커지면 Context, Redux, Recoil, Zustand 같은 전역 상태 관리도 검토해볼 수 있습니다.

// Zustand 예시
const useStore = create((set) => ({
  count: 0,
  increase: () => set((state) => ({ count: state.count + 1 }))
}));
전역 상태 관리 라이브러리는 상황에 맞게 선택하세요.
복잡도, 팀 규모, SSR 여부 등을 고려해 결정하는 것이 중요합니다.

✅ 마무리

React는 유연한 만큼 개발 방식도 다양합니다. 오늘 소개한 패턴들을 이해하고 프로젝트에 맞게 적용해보세요. 특히 협업이 많은 실무 환경에서는 이러한 패턴이 코드 일관성을 유지하고 유지보수를 수월하게 해줍니다.

이 외에도 Suspense, Error Boundary, HOC, Render Props 같은 패턴들도 있지만, 이번 글에서는 특히 실무에서 자주 사용되는 핵심 패턴 위주로 소개해봤습니다.

다음 글에서는 React 성능 최적화 팁이나 디자인 시스템 구축 경험에 대해서도 다뤄볼게요 :)

반응형