내가 MVVM을 활용해 확장 가능한 React Native 앱을 구조화하는 방법

발행: (2026년 4월 20일 PM 09:34 GMT+9)
5 분 소요
원문: Dev.to

Source: Dev.to

React Native 앱이 커지면 피할 수 없는 문제가 하나 생깁니다: 코드가 엉망이 되기 시작한다는 점입니다.
단순한 컴포넌트 구조였던 것이 서서히 다음과 같이 변합니다:

  • 서로 강하게 결합된 로직
  • 유지보수가 어려운 화면
  • 예측할 수 없는 상태 관리

저는 실제 서비스 앱을 개발하면서 이 문제를 겪었고, 그때부터 **MVVM (Model–View–ViewModel)**이라는 보다 구조화된 접근 방식을 채택하기 시작했습니다.

왜 React Native 앱은 확장하기 어려워지는가

많은 프로젝트에서 로직이 컴포넌트 내부에 들어가게 됩니다:

  • API 호출
  • 비즈니스 로직
  • 상태 변환

이로 인해 다음과 같은 문제가 발생합니다:

  • 가독성 저하
  • 테스트 어려움
  • 화면마다 중복된 로직

앱이 커질수록 상황은 더욱 악화됩니다.

MVVM이 해결해 주는 것

MVVM은 책임을 다음과 같이 분리합니다:

  • Model → 데이터 레이어 (API, 저장소, 타입)
  • View → UI 컴포넌트
  • ViewModel → 비즈니스 로직 + 상태 관리

이러한 분리는 UI를 깔끔하게 유지하고 로직을 재사용 가능하게 만들어 줍니다.

내 폴더 구조

제가 보통 기능을 구성하는 방식은 다음과 같습니다:

// /features/user
UserView.tsx          // View component
useUserViewModel.ts   // ViewModel hook
userModel.ts          // Model definitions
userService.ts        // Data fetching / storage
  • View는 렌더링을 담당
  • ViewModel은 로직을 관리
  • Model/Service는 데이터를 처리

예시: View vs ViewModel

View (UI 전용)

import React, { useEffect } from 'react';
import { Text } from 'react-native';
import { useUserViewModel } from './useUserViewModel';
import Loader from '../components/Loader';

const UserView = () => {
  const { user, loading, fetchUser } = useUserViewModel();

  useEffect(() => {
    fetchUser();
  }, []);

  if (loading) return ;
  return {user?.name};
};

export default UserView;

ViewModel (로직)

import { useState } from 'react';
import { getUser } from '../services/userService';

export const useUserViewModel = () => {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(false);

  const fetchUser = async () => {
    setLoading(true);
    const data = await getUser();
    setUser(data);
    setLoading(false);
  };

  return { user, loading, fetchUser };
};

프로덕션에서 잘 작동하는 이유

  • 로직을 별도로 테스트하기 쉬움
  • 비즈니스 로직 재사용 가능
  • UI 컴포넌트가 깔끔함
  • 팀 협업이 개선됨

가장 중요한 점은 동일한 로직을 여러 곳에서 다시 작성하지 않게 된다는 것입니다.

Redux와의 연계

Redux를 사용한다면:

  • 전역 상태는 Redux에 보관
  • 화면 별 로직은 ViewModel에 보관

이렇게 하면 불필요한 복잡성으로 Redux를 과부하 시키는 일을 피할 수 있습니다.

피해야 할 흔한 실수

  • 모든 것을 Redux에 넣기
  • UI와 비즈니스 로직을 섞어버리기
  • 작은 기능을 과도하게 설계하기

MVVM은 앱을 단순화하기 위한 것이지 복잡하게 만들기 위한 것이 아닙니다.

마무리 생각

React Native는 아키텍처를 강제하지 않으며, 이는 장점이자 단점이 될 수 있습니다.
초기에 구조를 정의하지 않으면 확장할 때 고통스러워집니다.

저에게 MVVM은 다음과 같은 면에서 간단하고 효과적인 방법이었습니다:

  • 코드 정리
  • 유지보수성 향상
  • 보다 예측 가능한 앱 구축

유일한 접근법은 아니지만, 실제 프로젝트에서 잘 작동하는 방법 중 하나입니다.

0 조회
Back to Blog

관련 글

더 보기 »