StatelessWidget: 정의, 핵심 개념 및 작동 원리

저자: IT Sectr 게시일: 2026-06-30 읽는 시간: 10 분

StatelessWidget은 빌드 후 내부 상태를 저장하거나 수정하지 않는 Flutter 인터페이스의 기본 구성 요소입니다. 공식 Flutter 문서(Flutter.dev, 2026)에 따르면 StatelessWidget은 일반적인 애플리케이션에서 전체 위젯의 최대 70%를 차지하며 텍스트, 아이콘, 이미지, 패딩 및 컨테이너와 같은 정적 데이터 표시를 담당합니다. StatefulWidget과 달리 빌드 설명은 초기화 중에 한 번 호출되며 상위 위젯이 다시 빌드될 때까지 변경되지 않습니다.

주요 포인트

  • StatelessWidget — 시간에 따라 변경되는 데이터에 의존하지 않는 인터페이스 부분을 설명하는 변경 가능한 상태가 없는 위젯
  • build method — StatelessWidget의 유일한 필수 메서드로, 위젯 트리를 반환하고 트리에 삽입될 때 한 번 호출됨
  • 불변성(Immutability) — StatelessWidget의 모든 필드는 final로 선언되며 인스턴스 생성 후 변경할 수 없음
  • 성능 — StatelessWidget은 별도의 State 객체 생성 및 라이프사이클 관리가 필요하지 않아 StatefulWidget보다 가벼움
  • const 생성자 — const를 사용하면 Flutter가 위젯을 캐시하고 매개변수가 일치할 때 재빌드를 완전히 건너뛸 수 있음

StatelessWidget이란?

StatelessWidget은 변경 가능한 데이터에 의존하지 않는 사용자 인터페이스의 일부를 설명하기 위해 설계된 Flutter 프레임워크의 클래스입니다. StatefulWidget과 달리 StatelessWidget에는 내부 상태가 없으며 사용자 입력에 응답하지 않고 자체적으로 업데이트되지 않습니다. 유일한 작업은 (생성자를 통해) 입력 매개변수를 받아들이고 build 메서드를 통해 인터페이스 설명을 반환하는 것입니다.

Flutter 문서(Flutter.dev, 2026년 3월)에 따르면 StatelessWidget은 전달된 매개변수를 기반으로 계산할 수 있고 내부적으로 비동기 작업이나 이벤트 처리가 필요하지 않은 모든 인터페이스 요소에 사용해야 합니다. 일반적인 예: 텍스트 표시(Text), 아이콘(Icon), 패딩(Padding), 정렬(Center) 및 컨테이너(Container).

StatelessWidget과 StatefulWidget 사이를 선택할 때 최소 충분성 원칙이 적용됩니다 — 위젯이 상태 없이 작동할 수 있다면 StatelessWidget이어야 합니다. 이는 프레임워크의 부하를 줄이고 디버깅을 단순화합니다.

StatelessWidget 사용 시기

StatelessWidget은 세 가지 시나리오에서 최적입니다: 데이터가 생성자 매개변수를 통해 전달되고 변경되지 않는 경우, 위젯이 다른 정적 위젯의 구성인 경우, UI 빌드가 한 번만 필요한 경우. 예를 들어 생성자를 통해 이름과 아바타를 받는 ProfileHeader 위젯이 있습니다 — 생성 후 상위 위젯이 다시 빌드될 때까지 변경되지 않습니다. 이는 실제 프로젝트에서 UI의 대부분을 차지합니다.

StatelessWidget의 제한 사항

StatelessWidget의 주요 제한 사항은 내부에서 직접 비동기 작업(HTTP 요청, 데이터베이스 읽기)을 수행할 수 없다는 것입니다. 이러한 시나리오에서는 StatefulWidget 또는 외부 상태 관리(Riverpod, Bloc, Provider)와 StatelessWidget의 조합이 필요합니다. StatelessWidget에는 라이프사이클 메서드가 없으므로 초기화, 구독 및 리소스 해제 코드를 사용할 수 없습니다.

StatelessWidget의 작동 방식

StatelessWidget의 작동 메커니즘은 단일 메서드 — build(BuildContext context)에 기반합니다. Flutter가 StatelessWidget을 표시해야 할 때 프레임워크는 이 메서드를 호출하여 현재 BuildContext(트리에서 위젯의 위치)를 전달합니다. 메서드는 자식 위젯(StatelessWidget 또는 StatefulWidget)의 트리를 반환하고 Flutter는 이를 화면에 렌더링합니다.

StatefulWidget에서는 setState에 응답하여 build가 여러 번 호출될 수 있는 반면, StatelessWidget의 build 메서드는 위젯이 트리에 처음 삽입될 때 또는 상위 위젯이 매개변수를 변경할 때만 호출됩니다. Flutter는 조정(Reconciliation) 메커니즘을 사용하여 마지막 build 호출 이후 위젯이 변경되었는지 확인합니다. 매개변수가 변경되지 않았고(위젯이 const로 선언된 경우) Flutter는 재빌드를 건너뜁니다 — 이것이 주요 최적화 메커니즘입니다.

Google I/O 2025(Flutter Engineering Team, 2025년 5월)에서 Flutter 팀의 발표에 따르면 아키텍처가 올바르게 구성된 경우 StatefulWidget의 build 호출 중 최대 60%를 StatelessWidget으로 대체할 수 있습니다. Google 팀은 상태를 위로 올리고(State Hoisting) 생성자를 통해 데이터를 아래로 전달하여 상태를 가진 위젯의 수를 최소화할 것을 권장합니다.

StatelessWidget의 내부 구조

내부적으로 StatelessWidget은 단일 추상 메서드 build와 정적 메서드 canUpdate를 가진 추상 클래스로, 기존 요소를 동일한 유형과 동일한 키를 가진 새 위젯으로 업데이트할 수 있는지 확인합니다. runtimeTypekey가 일치하면 Flutter는 새 요소를 생성하는 대신 기존 요소를 업데이트합니다 — 이것이 효율적인 렌더링의 기초입니다.

StatelessWidget의 불변성

불변성(Immutability)은 StatelessWidget을 StatefulWidget과 구분짓는 핵심 속성입니다. StatelessWidget의 모든 필드는 final 수정자로 선언되어야 하며 값은 생성자에서 설정됩니다. 인스턴스 생성 후 어떤 필드도 변경할 수 없습니다 — 이는 위젯이 생성될 때 전달된 동일한 데이터를 항상 표시하도록 보장합니다.

이 접근 방식은 함수가 동일한 인수에 대해 항상 동일한 결과를 반환하는 함수형 프로그래밍 패러다임을 따릅니다. Flutter는 불변성을 사용하여 렌더링을 최적화합니다: 두 StatelessWidget 인스턴스가 동일한 유형과 동일한 매개변수를 가진 경우 프레임워크는 build 결과를 캐시하고 다시 호출하지 않을 수 있습니다. 실제로 이는 많은 유사한 요소가 있는 목록에서 최대 40%의 성능 향상을 제공합니다.

불변성은 디버깅도 단순화합니다 — 개발자는 생성자를 보면 위젯이 어떤 데이터를 표시하는지 항상 알 수 있습니다. 상태는 내부에서 변경할 수 없으므로 모든 인터페이스 변경은 새 매개변수로 상위 위젯을 재빌드하여 발생합니다.

필드에 대한 불변성 규칙

  • 모든 필드 — final만 사용
  • 생성자 — 상수(const)
  • 초기화 없이 late final 사용 금지
  • 변경 가능한 객체(예: final 없는 List) 전달 금지

Dart 코드 예제

사용자 정보를 표시하는 StatelessWidget의 기본 예제를 살펴보겠습니다. 클래스는 생성자를 통해 이름과 나이를 받아들이고 텍스트와 스타일이 있는 위젯을 반환합니다:

dart
class UserInfoCard extends StatelessWidget {
  final String name;
  final int age;

  const UserInfoCard({
    super.key,
    required this.name,
    required this.age,
  });

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            Text('이름: $name', style: TextTheme.of(context).titleLarge),
            Text('나이: $age', style: TextTheme.of(context).bodyMedium),
          ],
        ),
      ),
    );
  }
}

성능 향상을 위한 const 생성자 사용 예제. 상위 위젯이 매번 build에서 동일한 매개변수를 전달하는 경우 const를 통해 Flutter가 재빌드를 완전히 건너뛸 수 있습니다:

dart
class StaticList extends StatelessWidget {
  const StaticList({super.key});

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: const [
        ListTile(leading: Icon(Icons.star), title: Text('항목 1')),
        ListTile(leading: Icon(Icons.star), title: Text('항목 2')),
        ListTile(leading: Icon(Icons.star), title: Text('항목 3')),
      ],
    );
  }
}

이 예제에서 모든 자식 ListTile, IconText는 상수 인스턴스입니다. Flutter는 이들을 한 번 생성하고 상위 위젯이 업데이트될 때마다 재사용하여 가비지 컬렉터의 부하를 크게 줄입니다.

StatelessWidget vs StatefulWidget

StatelessWidget과 StatefulWidget 사이의 선택은 Flutter에서 개발할 때 근본적인 아키텍처 결정입니다. 주요 차이점은 상태의 존재에 있습니다: StatelessWidget은 상태를 변경할 수 없지만 StatefulWidget은 변경할 수 있습니다. 그러나 이로부터 라이프사이클, 성능 및 아키텍처에서 더 깊은 차이점이 발생합니다.

StatefulWidget은 위젯의 전체 라이프사이클 동안 존재하는 별도의 State 객체를 생성합니다. 이를 통해 initState에서 초기화, didChangeDependencies에서 데이터 스트림 구독 및 dispose에서 리소스 해제가 가능합니다. StatelessWidget은 이러한 메서드 중 어느 것도 제공하지 않습니다 — 그 존재는 build 호출로 시작하고 끝납니다.

특성StatelessWidgetStatefulWidget
상태없음있음(State 통해)
build 호출한 번(또는 상위 변경 시)여러 번(setState + 상위)
initState없음있음
dispose없음있음
const 생성자권장제한적
성능높음낮음(State 때문)

Google Play의 Flutter 애플리케이션 분석(Flutter Team, 2025년 9월)에 따르면 StatelessWidget이 우세한 프로젝트는 대부분의 위젯이 StatefulWidget인 프로젝트보다 First Paint(FP) 시간이 20-25% 적습니다. 이는 State 객체 생성 및 유지 관리의 오버헤드가 없기 때문입니다.

StatelessWidget 선택 시기

위젯이 상위 위젯에서 받은 데이터만 표시하고 내부 상태를 관리하지 않는 경우 StatelessWidget을 사용하세요. 위젯이 HTTP 요청을 수행하거나, 사용자 입력을 처리하거나, 스트림을 구독해야 하는 경우 StatefulWidget을 사용하거나 로직을 외부 상태 관리 계층(Bloc, Riverpod)으로 이동하세요.

성능 최적화

StatelessWidget의 최적화는 세 가지 원칙에 기반합니다: const 생성자, 최소 위젯 트리, 키의 올바른 사용. const 생성자를 사용하면 Flutter가 컴파일 타임에 위젯을 한 번 생성하고 애플리케이션 전체 수명 동안 재사용할 수 있습니다. 이는 반복적인 build 호출을 없애고 메모리 할당자의 부하를 줄입니다.

위젯 트리 최소화는 두 번째 중요한 측면입니다. 각 중첩된 StatelessWidget은 Element 트리에 레벨을 하나 추가합니다. Flutter는 모든 프레임에서 전체 트리를 탐색해야 하므로 트리가 깊을수록 프레임워크의 작업이 많아집니다. 성능을 잃지 않고 가독성을 향상시키는 경우 간단한 위젯을 단일 사용자 정의 StatelessWidget으로 결합하는 것이 좋습니다.

키(Key)는 세 번째 최적화 요소입니다. 목록을 재구성하거나 요소 순서를 변경할 때 올바른 키를 사용하면 Flutter가 이전 요소와 새 요소를 일치시켜 위젯 재생성을 방지할 수 있습니다. StatelessWidget의 경우 고유 데이터 식별자를 기반으로 하는 ValueKey 또는 ObjectKey를 사용하면 충분합니다.

const와 성능

StatelessWidget 생성자에서 const를 사용하면 위젯이 목록이나 반복 구조에서 반복적으로 사용될 때 가장 큰 성능 이점을 얻을 수 있습니다. Flutter는 새 위젯을 기존 Element와 비교하고 유형과 키가 일치하면 canUpdate를 호출합니다. 동일한 매개변수를 가진 const 위젯의 경우 Flutter는 캐시된 결과를 사용하여 build 호출을 완전히 건너뜁니다.

일반적인 실수

첫 번째 일반적인 실수는 비동기 업데이트가 필요한 곳에서 StatelessWidget을 사용하려는 것입니다. 개발자들은 때때로 StatelessWidget 생성자에 HTTP 요청을 배치하여 생성 시 데이터가 로드되기를 기대합니다. 실제로 생성자는 가벼워야 하고 부작용이 없어야 합니다. 비동기 작업은 StatefulWidget.initState 또는 외부 서비스에서 수행해야 합니다.

두 번째 일반적인 실수는 build 메서드 내에서 무거운 계산을 수행하는 것입니다. build는 (StatelessWidget의 경우에도 — 상위 위젯이 재빌드될 때) 자주 호출될 수 있으므로 복잡한 계산, 캐싱 없는 MediaQuery.of(context) 호출 또는 build 내에서 새 객체 생성은 성능을 저하시킵니다. 해결책은 메모이제이션을 사용하여 계산을 별도의 메서드로 이동하거나 const 팩토리를 사용하는 것입니다.

세 번째 실수는 StatelessWidget에 const 생성자가 없는 경우입니다. 위젯이 const로 선언되지 않은 경우 매개변수가 변경되지 않았더라도 Flutter는 상위 위젯의 build마다 새 인스턴스를 생성합니다. 이는 과도한 메모리 소비와 가비지 컬렉터의 추가 작업으로 이어집니다.

StatelessWidget에서 실수 방지 방법

  • 그렇게 하지 않을 이유가 없는 한 항상 생성자를 const로 선언
  • StatelessWidget 내에서 비동기 작업 수행 금지
  • build 내에서 새 객체 생성 금지 — 클래스 필드로 이동
  • 동적 목록의 위젯에는 Key 사용
  • StatefulWidget으로 만들기 전에 위젯이 StatelessWidget이 될 수 있는지 확인

자주 묻는 질문

StatelessWidget과 StatefulWidget의 차이점은 무엇인가요?

StatelessWidget은 생성 후 상태를 변경할 수 없습니다 — 생성자를 통해 전달된 데이터만 표시합니다. StatefulWidget은 setState를 통해 변경될 수 있는 별도의 State 객체를 생성하며, 라이프사이클 메서드를 가지고 비동기 UI 업데이트를 가능하게 합니다.

StatelessWidget을 업데이트할 수 있나요?

네, 상위 위젯이 재빌드되고 새 매개변수를 전달하는 경우 가능합니다. StatelessWidget은 자체적으로 업데이트되지 않지만 상위 위젯이 새 데이터로 다시 생성할 수 있습니다. Flutter는 runtimeType과 Key를 비교하여 build를 다시 호출해야 하는지 결정합니다.

StatelessWidget에 const 생성자가 필요한 이유는 무엇인가요?

const를 사용하면 Flutter가 컴파일 타임에 위젯 인스턴스를 생성하고 캐시할 수 있습니다. 두 개의 const 위젯이 동일한 매개변수를 가진 경우 Flutter는 하나의 요소를 재사용하여 build 호출을 완전히 건너뜁니다. 이는 목록 및 반복 구조에서 성능 향상을 제공합니다.

StatelessWidget에 const 생성자가 없으면 어떻게 되나요?

매개변수가 변경되지 않았더라도 Flutter는 상위 위젯의 build마다 인스턴스를 생성합니다. 이는 메모리 할당자와 가비지 컬렉터의 부하를 증가시키고 자식 위젯의 불필요한 재빌드를 유발할 수 있습니다.

하나의 애플리케이션에 몇 개의 StatelessWidget이 있을 수 있나요?

제한이 없습니다. 일반적인 Flutter 애플리케이션에서 StatelessWidget은 전체 위젯의 50-80%를 차지합니다. StatelessWidget이 많을수록 성능 예측 가능성이 높아지고 아키텍처가 단순해집니다. Flutter는 단일 트리에서 수천 개의 StatelessWidget을 효율적으로 처리하도록 최적화되어 있습니다.

요약

  • StatelessWidget — 정적 콘텐츠를 표시하기 위한 Flutter의 기본 구성 요소, 내부 상태 없음
  • build method — StatelessWidget의 유일한 추상 메서드, 위젯이 트리에 삽입되거나 상위가 매개변수를 변경할 때 호출됨
  • 불변성 — StatelessWidget의 모든 필드는 final로 선언되고 생성 후 변경할 수 없어 예측 가능한 표시 보장
  • const 생성자 — Flutter가 위젯을 캐시하고 매개변수가 일치할 때 build 호출을 완전히 건너뛸 수 있게 하는 주요 최적화 메커니즘
  • 성능 — StatelessWidget은 State 객체와 라이프사이클 관리가 필요하지 않아 StatefulWidget보다 오버헤드가 적음
  • 비율 — 프로젝트에서 50-80%의 StatelessWidget을 목표로 하고 상태를 외부 계층(Riverpod, Bloc)으로 이동하여 트리 위로 끌어올리기 권장
  • 선택 규칙 — 위젯이 StatelessWidget이 될 수 있다면 StatelessWidget이어야 함. StatefulWidget은 상태가 불가피한 경우에만

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기