inblog logo
|
하쎄의 기술 일기장
    Flutter

    [Flutter] 화면의 비동기 처리 방식(StatefulWidget vs StatelessWidget)

    8. 화면의 비동기 처리 방식(StatefulWidget vs StatelessWidget)
    하세연's avatar
    하세연
    Oct 02, 2024
    [Flutter] 화면의 비동기 처리 방식(StatefulWidget vs StatelessWidget)
    Contents
    1. StatefulWidget 과 StatelessWidget 의 의미2. StatefulWidget 과 StatelessWidget 의 사용 방법3. StatefulWidget 과 StatelessWidget 의 예시4. 사용 방식5. 차이점 요약
     

    1. StatefulWidget 과 StatelessWidget 의 의미

    StatefulWidget과 StatelessWidget은 Flutter에서 위젯을 정의할 때 사용되는 두 가지 주요 클래스입니다. 이 두 위젯은 화면에 UI를 렌더링하지만, 상태(State)를 관리하는 방식에서 큰 차이가 있습니다.
    💡

    1. StatelessWidget

    • 상태가 없는 위젯입니다.
    • 변경되지 않는 데이터(immutable data)를 기반으로 UI를 렌더링합니다.
    • 위젯이 빌드되고 난 후에 상태가 변경되지 않으므로, 한 번 그려지면 그 UI는 다시 변하지 않습니다.
    • 데이터를 변경하거나 업데이트할 필요가 없고, 정적인 화면을 나타낼 때 주로 사용됩니다.

    특징:

    • 상태를 유지하지 않음: StatelessWidget은 내부적으로 상태를 저장하지 않으며, 렌더링할 때 주어진 데이터를 기반으로 UI를 그리기만 합니다.
    • 재렌더링: 만약 UI가 변경되어야 한다면, 전체 위젯을 재생성해야 합니다.
     
    💡

    2. StatefulWidget

    • 상태를 유지할 수 있는 위젯입니다.
    • 위젯이 빌드된 이후에도 상태(State)를 변경하고, 그에 따라 UI가 변경될 수 있습니다.
    • 사용자 입력, 네트워크 요청 등으로 인해 데이터를 업데이트하고 싶을 때 StatefulWidget을 사용합니다.
    • 상태는 State 객체에 저장되며, setState() 메서드를 호출하면 상태를 변경하고 UI를 다시 렌더링할 수 있습니다.

    특징:

    • 상태 관리: StatefulWidget은 동적인 UI를 구현할 때 사용됩니다. State 객체가 위젯의 상태를 저장하고, UI를 업데이트할 때는 setState() 메서드를 호출합니다.
    • 라이프사이클: StatefulWidget은 자체 라이프사이클을 가지고 있습니다. 위젯이 생성되고, 초기화되며, 소멸될 때까지의 단계들을 처리할 수 있습니다. 대표적인 라이프사이클 메서드로 initState()와 dispose()가 있습니다.
     

    2. StatefulWidget 과 StatelessWidget 의 사용 방법

    notion image
    화면의 데이터를 통신으로 받아 재구성할 때 일부분만 변경함에도 불구하고 화면 전체를 새로 그리는 것은 상당히 비효율적인 방식이다.
    Flutter 에서는 고정인 화면을 사용할 때 StatelessWidget 을 그리고 데이터를 통신 받아 화면이 바뀌는 부분은 StatefulWidget 방식을 사용한다.
    위의 그림을 예시로 설명하자면,
    main 1번 ( 2번 )
    class 2번 ( 3번, 4번, 5번 )
    class 3번 ( 6번 )
    class 4번 ( 7번 )
    class 5번 ( 8번, 9번 )
    왼쪽의 그림의 상황에서 2번에서 원하는 데이터를 불러오는 기능이 있다면 2번 하나를 위해 3번~9번까지 관련 없는 부분이더라도 상관없이 화면이 전체가 reloading 될 것이다.
    반면에 오른쪽 그림처럼 데이터를 불러오는 기능을 최대한 바깥쪽으로 5번으로 포장하여 뺀다면 화면은 5, 8, 9 번만 reloading 될 것이다.
    이처럼 화면을 부분 reloading 하는 기능을 가지고 있다면 StatefulWidget 을 하위 메서드로 구분지어 분리 시키는 것이 효율적이다.
     

    3. StatefulWidget 과 StatelessWidget 의 예시

    import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: ShopPage(), ); } } class ShopPage extends StatefulWidget { @override State<ShopPage> createState() => _ShopPageState(); } class _ShopPageState extends State<ShopPage> { List<String> imageList = [ "https://picsum.photos/id/100/200/200", "https://picsum.photos/id/101/200/200" ]; int selectedIndex = 0; @override Widget build(BuildContext context) { print("ShopPage 그림 그려짐"); return Scaffold( appBar: AppBar(title: Text("쇼핑카트")), body: Column( children: [ //1. 이미지를 건들이고 이미지의 크기를 강제로 바꾸려면 부모에 aspectRtio 다른것들은 sized 박스 AspectRatio( aspectRatio: 3 / 2, child: Image.network( imageList[selectedIndex], fit: BoxFit.cover, ), ), //2. 버튼2개 Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Container( width: 70, height: 70, //decoration을 사용하면 여기에 color를 지정해야된다 container에 color를 사용못하게 막았다 그냥 문법 decoration: BoxDecoration( color: Colors.grey, borderRadius: BorderRadius.circular(20), ), child: IconButton( onPressed: () { selectedIndex = 0; print("selectedIndex : $selectedIndex "); setState(() {}); }, icon: Icon(Icons.access_alarm_sharp)), ), Container( width: 70, height: 70, //decoration을 사용하면 여기에 color를 지정해야된다 container에 color를 사용못하게 막았다 그냥 문법 decoration: BoxDecoration( color: Colors.red, borderRadius: BorderRadius.circular(20), ), child: IconButton( onPressed: () { selectedIndex = 1; print("selectedIndex : $selectedIndex "); setState(() {}); }, icon: Icon(Icons.accessibility_sharp)), ), ], ), ], ); } }
    해당 코드는 버튼 두 개를 이용해 각각의 이미지를 불러오도록 하는 것이다.
    현재의 코드에는 ShopPage 메서드에 StatefulWidget 이 설정되어있다. 그렇기 때문에 버튼을 누른다면 ShopPage의 해당 영역 부분만 reloading 된다. 만약 StatefulWidget 이 main으로 실행되는 MyApp에 적용되어 있다면 ShopPage 뿐만 아니라 이후 작성하는 다른 코드 부분의 영역에도 적용되어 화면 전체가 reloading 되는 것이다.
     

    4. 사용 방식

    extends StatefulWidget 부분에 커서를 올리고 alt + Enter 를 누르면 그림과 같이 나오고 상태 메서드를 생성하게 된다.
    notion image
     
    이를 각각 버튼마다 status 를 설정해놓고 버튼을 누를 때 이벤트를 발생시키는 영역에
    onPressed: () { selectedIndex = 1; print("selectedIndex : $selectedIndex "); setState(() {});
    다음과 같이 setState(() {}); 를 넣어주면 상태가 적용되며 화면이 부분 reloading 된다.
     

    5. 차이점 요약

    ㅤ
    StatelessWidget
    StatefulWidget
    상태 관리
    상태를 유지하지 않음
    상태를 유지하고 변경 가능
    UI 갱신
    UI가 고정되어 변화하지 않음
    setState()로 상태 변경 시 UI 갱신
    라이프사이클
    없음
    있음 (initState(), dispose())
    사용 시점
    정적인 UI, 변하지 않는 값
    동적인 UI, 상태 변화가 필요한 경우
    • StatelessWidget은 정적인 데이터를 표시할 때 적합하고,
    • StatefulWidget은 상태 변화가 필요한 동적인 UI를 구현할 때 적합합니다.
    이러한 차이를 통해, 애플리케이션의 요구 사항에 맞는 위젯을 선택할 수 있습니다.
    Share article

    하쎄의 기술 일기장

    RSS·Powered by Inblog