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