inblog logo
|
harimmon
    플러터

    [플러터] 12. setState

    백하림's avatar
    백하림
    May 29, 2025
    [플러터] 12. setState
    Contents
    전체 rebuild전체 rebuild전체 rebuild부분 rebuild

    전체 rebuild

    import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: HomePage(), ); } } class HomePage extends StatefulWidget { @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { // 1. 상태 int num = 1; // 2. 행위 void increase() { num++; setState(() {}); // rebuild } @override Widget build(BuildContext context) { print("rebuild 됨"); return Scaffold( appBar: AppBar(), body: Center( child: Text("${num}", style: TextStyle(fontSize: 50)), ), floatingActionButton: FloatingActionButton( child: Icon(Icons.add), onPressed: increase, ), ); } }
    notion image

    전체 rebuild

    🔥
    1. 분리 없이 코드를 작성했음
    1. 증가 버튼을 누르면 숫자가 증가됨
    1. 원하는 건 부분 rebuild인데 지금은 전체가 rebuild 되고 있음
    import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: HomePage(), ); } } class HomePage extends StatefulWidget { @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { int num = 1; @override Widget build(BuildContext context) { return Container( color: Colors.yellow, child: Padding( padding: const EdgeInsets.all(20.0), child: Column( children: [ Expanded( child: Container( color: Colors.red, child: Align( child: Text( "${num}", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 100, decoration: TextDecoration.none), ), ), ), ), Expanded( child: Container( color: Colors.blue, child: Align( child: ElevatedButton( style: ElevatedButton.styleFrom(backgroundColor: Colors.red), onPressed: () { num++; setState(() {}); }, child: Text( "증가", style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 100, ), ), ), ), ), ), ], ), ), ); } }
    notion image

    전체 rebuild

    🔥
    context를 분리하니까 상태가 있는 쪽에서 행위를 가져야 하는데 행위는 바텀에서 가지고 있음
    위에 상태를 변경하기 위해서 바텀에서 행위를 가져야 하는데 가질 수가 없음
    그래서 결국 부모가 스테이트 풀이 되고 전체 리로드 됨
    import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: HomePage(), ); } } class HomePage extends StatefulWidget { const HomePage({Key? key}) : super(key: key); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { int num = 1; void increase() { num++; setState(() {}); } @override Widget build(BuildContext context) { return Container( color: Colors.yellow, child: Padding( padding: const EdgeInsets.all(20), child: Column( children: [ Expanded(child: HeaderPage(num)), Expanded(child: const MiddlePage(1)), Expanded(child: const MiddlePage(1)), Expanded(child: BottomPage(increase)), ], ), ), ); } } class HeaderPage extends StatelessWidget { int num; HeaderPage(this.num); @override Widget build(BuildContext context) { print("header"); return Container( color: Colors.red, child: Align( child: Text( "${num}", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 100, decoration: TextDecoration.none), ), ), ); } } class BottomPage extends StatelessWidget { Function increase; BottomPage(this.increase); @override Widget build(BuildContext context) { print("bottom"); return Container( color: Colors.blue, child: Align( child: ElevatedButton( style: ElevatedButton.styleFrom(backgroundColor: Colors.red), onPressed: () { print("버튼 클릭됨"); increase(); }, child: Text( "증가", style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 100, ), ), ), ), ); } } class MiddlePage extends StatelessWidget { final num; const MiddlePage(this.num); @override Widget build(BuildContext context) { return Container( color: Colors.white, ); } }
    notion image

    부분 rebuild

    🔥
    진짜 부모 (MyApp, HomePage - Stateless) └─ 가짜 부모 (Middle - Stateful) ├─ 상태 자식 (Top) ├─ 중간 자식 (→ 없음 또는 상태 전달만) └─ 행위 자식 (Bottom - 버튼)
    행위 위젯(Bottom)이 호출한 함수는 상태를 가진 중간 위젯(Middle)에서 setState()를 실행시키고, 이로 인해 중간 위젯만 리렌더링되며, 상태값을 전달받은 상태 위젯(Top)만 실제 UI가 변경됨.
    import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: HomePage(), ); } } class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { print("홈페이지 빌드"); return Scaffold( body: Middle(), ); } } // 가짜 부모 << 혼자만 Stateful 이다 class Middle extends StatefulWidget { const Middle({ super.key, }); @override State<Middle> createState() => _MiddleState(); } class _MiddleState extends State<Middle> { int num = 1; void increase() { num++; setState(() {}); } @override Widget build(BuildContext context) { return Column( children: [ Expanded( child: Top(num), ), Expanded( child: Bottom(increase), ), ], ); } } class Bottom extends StatelessWidget { Function increase; Bottom(this.increase); @override Widget build(BuildContext context) { return Center( child: Container( child: ElevatedButton( onPressed: () { increase(); }, child: Icon(Icons.add), ), ), ); } } class Top extends StatelessWidget { int num; Top(this.num); @override Widget build(BuildContext context) { return Center( child: Container( child: Text("$num", style: TextStyle(fontSize: 50)), ), ); } }
    notion image
     
    Share article

    harimmon

    RSS·Powered by Inblog