티스토리 뷰

 

플러터를 시작하시는 분들은 상태가 변화하였다고 프레임워크에 이를 알리기 위해 setState() 함수를 호출합니다.

 

모든 위젯의 상위 위젯을 RootPage라고 정의하고 여러 페이지를 이동한 상황에서 사용자가 인위적인 방법으로 테마를 다크로 설정하였다면, 최상위 위젯인 RootPage의 setState() 함수를 호출하면 되지 않나라고 간단하게 생각하는 분이 있을 겁니다.

 

하지만 이러한 방법은 setState() 함수가 호출된 상태만이 업데이트되었다고 알리는 행위이기 때문에 당연히 실패할겁니다.

(그 하위 위젯들 모두 상태가 변화했다고 정의하는 것이 아닙니다.)

 

이는 당연히 비효율적인 빌드를 방지하는 매우 효율적인 기법입니다.

 

그렇다고 해서 생명주기 함수인 didUpdateWidget() 함수를 오버라이드하여 상위 위젯이 변화했을 때 자신도 상태가 변화했다고 정의한다면 이는 매우 비효율적인 행위입니다.

 

개발자로서 절대 해서는 안되는 행위인 것이죠.

해당 상황에서는 간단하게 그냥 다음 프레임에 재빌드가 필요하다고 정의하는 함수를 호출합니다.

 

bash

element.markNeedsBuild();

 

실제로 제가 사용하는 코드를 들고와보도록 하겠습니다.

 

bash

/// [RootPage]는 모든 위젯의 상위 위젯입니다. /// /// - [RootPage.rebuild]를 호출하여 모든 위젯을 다시 그릴 수 있습니다. class RootPage extends StatefulWidget { const RootPage({super.key}); static late RootPageRebuild rebuild; @override State<RootPage> createState() => _RootPageState(); } class _RootPageState extends State<RootPage> with WidgetsBindingObserver { /// 모든 자식 위젯을 다시 빌드합니다. static void rebuildAllChildren(BuildContext context) { // 해당 위젯의 모든 하위 위젯들을 다음 프레임에 재구성해야할 위젯으로 정의합니다. void rebuild(Element element) { // 해당 Element를 다음 프레임에 재구성해야할 위젯으로 정의합니다. // // - 한 프레임에 Element를 두 번 빌드하는 것은 비효율적이기 때문에, // 애플리케이션과 위젯은 빌드 자체가 아니라 프레임이 시작되기 전 이벤트 핸들러 동안에만 // 위젯을 재구성하도록 구조화되어야 합니다. // (그냥 위젯들을 리빌드시킨 답시고 일일이 한 위젯을 빌드시키지 말라는 뜻입니다 // 한 프레임을 기준으로 빌드를 하라는 뜻입니다) // element.markNeedsBuild(); element.visitChildren(rebuild); } // 현재 context를 Element로 정의하고 하위 위젯을 참조합니다. (context as Element).visitChildren(rebuild); } @override void initState() { super.initState(); RootPage.rebuild = () { // 현재 화면이 그려지고 있는 상태라면 (렌더링 중이면) final isFrameRendering = WidgetsBinding.instance.schedulerPhase != SchedulerPhase.idle; if (isFrameRendering) { setState(() => rebuildAllChildren(context)); } else { // 화면이 그려지지 않는 상태라면 해당 작업이 완료된 후 호출됩니다, // 그렇지 않은 경우라면 호출되지 않습니다 다시 그릴때까지 호출을 보류합니다. // // 만약 그리고 있지 않은 상태라면 addPostFrameCallback 함수를 사용하지 마세요. WidgetsBinding.instance.addPostFrameCallback((_) { setState(() => rebuildAllChildren(context)); }); } }; } @override Widget build(BuildContext context) { return ...; } }

 

이해가 되셨을거라고 생각하고 그럼 이만.

 

관련 패키지

 

flutter_rebuildable | Flutter package

This package that provides widgets to help rebuild all descendant widgets or all widgets in the entire application.

pub.dev

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함