상태관리 - 실습하기

송민경's avatar
Apr 15, 2024
상태관리 - 실습하기

  • 컨텍스트 분리의 장점 : 변하는 부분만 리로드 가능함
notion image
notion image
  • 밑에 것만 리로드 됨
notion image
 
  • bottom은 header의 setState가 필요함
부모가 자식에게 값을 넘길 순 있지만 밑에 있는 페이지가 위에 값을 전달해줄 수 없음
⇒ 공통 조상 다시 그리기
노란색 전체 배경에서 상태 관리하기
 
H = 조상 / T = header / B = bottom
notion image
  • 컨텍스트 분리 : 부분 리로드
상태값과 상태값을 변경 메서드가 분리되어 있으면 공통 조상에서 상태(변수)를 관리해야 함
notion image
  • 매개변수로 함수 전달 가능함
  • 조상이 리로드되서 포함된 모든 것이 그려짐
notion image
  • 공통 조상으로 리로드되는데 컴포넌트로 분리한 이유
notion image
  • 공통 조상을 찾아 리로드하기
notion image
  • 컴포넌트 설계시 공통 분모를 최단 거리로 만들어야 함!!
한 줄로 쫙 쫘서 쪼개야 가능함
notion image
  • stateless도 stateful의 자식이면 다시 그려짐
notion image
  • stateless만 리로드 하려면 상태를 외부에서 가져오면 됨
상태를 클래스로 빼서 관리함 → observer 패턴 적용
여러 군데에서 변경해야 될 수 있음
notion image
  • 구독자들은 관찰하고 있다고 자기들을 스스로 다시 그릴 수 있음
 
  • Publish-Subscribe 소프트웨어 아키텍처 패턴 중 하나 컴포넌트 간의 통신을 가능하게 하는 방법 중 하나 이벤트 기반 아키텍처에서 주로 사용 발행자(Publisher)와 구독자(Subscriber) 간의 관계를 정의
    • 퍼블리시(Publish)
    • 이벤트나 메시지를 생성 해당 이벤트를 전달할 때 채널이나 토픽을 선택 생성한 이벤트를 특정 채널에 전송
    • 서브스크라이브(Subscribe) 발행자가 전달한 이벤트를 감지 그 이벤트에 반응하여 적절한 동작을 수행 특정 채널에 "구독"하여 해당 채널로부터 이벤트를 수신
notion image
  • stateful과 stateless 상태 변경
notion image
  • 조상으로 상태 관리
상태 값을 가지고 있는 컴포넌트와 상태를 변경하는 메서드가 있는 컴포넌트가 있음
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; void increase(){ num++; setState(() {}); } @override Widget build(BuildContext context) { return Container( color: Colors.yellow, child: Padding( padding: const EdgeInsets.all(20.0), child: Column( children: [ Expanded(child: HeaderPage(num)), 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, ), ), ), ), ); } }
 
  • 상태를 변경하는 메서드에 객체의 내용이 같을 경우
  • 시리얼라이즈드 넘버?
  • new가 몇번이 되든 모든 데이터(객체의 상태 값)가 동일하면 싱글톤으로 관리해도 됨
하나만 띄우고 다 그리면 됨 = 하나의 객체만 보고 그림을 그림
 
 
const
  • 한번만 new가 됨
  • build 되면 다시 그림은 그려지지만 객체 생성은 안됨
  • 상태가 없어야 함
  • 매개변수가 있으면 변경될 가능성이 있음
notion image
notion image
notion image
notion image
  • 상수를 사용해서 오류가 안 남
notion image
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
Share article

vosw1