HIT해

context 본문

Flutter/CS

context

힛해 2025. 8. 12. 14:40
728x90

BuildContext

위젯 트리 내에서 현재 위젯의 위치를 나타내는 핸들 역할을 하는 객체
  • build() 메서드 내에서 인자로 전달되며, context를 통해 위젯 트리 상의 상위 위젯, 상태 관리 객체 등 다양한 정보를 탐색할 수 있다
  • 위젯 트리에서 조상 위젯을 탐색하거나, 데이터를 내려주고 받는 데 꼭 필요한 연결고리 역할을 한다.

예제

void main() {
  runApp(MyApp()); // MyApp은 최상위 위젯
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: HomeScreen(),
    );
  }
}

 

  • runApp() 이 호출되면 Flutter는 최상위 위젯부터 build(BuildContext context) 메서드를 호출하며 위젯 트리를 생성한다
  • 각 위젯의 build() 메서드는 자신의 자식 위젯 트리를 반환하고, 이때 BuildContext 객체가 각 위젯에 전달된다
  • BuildContext는 현재 위젯이 트리 내 어디에 위치를 알려주고, 그 위치를 기준으로 필요한 리소스나 상태에 접근할 수 있다.

Provider의 context.watch,read

void main() {
  runApp(
    Provider<int>.value(
      value: 42,
      child: MyApp(),
    ),
  );
}

 

Provider는 상태, 데이터를 위젯 트리를 의존해서 제공한다. ( 트리 탐색형 )

어떤 Data를 하위 위젯이 쓰게 하려면, 그 Data를 위젯 트리의 조상 부분 Provider로 감싸야 한다.

BuildContext로부터 위젯 트리를 거슬러 올라가며 가장 가까운 조상 Provider를 찾아내고, 거기서 상태 또는 객체를 가져온다

정리하자면 위젯 트리라는 경로를 탐색해서 상태를 찾기때문애 BuildContext가 필요하다

 

  1. context.read()나watch를 호출하면, 현재 BuildContext 위치에서 위로 올라가며 가장 가까운 Provider를 찾아 참조
  2. 이때 빌드 과정에서는 Provider가 위젯 트리 내 위치가 명확하기 때문에 위젯 트리 탐색을 통한 연결을 만들고 구독을 합니다.
  3. 상태가 바뀌면 ChangeNotifier 같은 내부 메커니즘이 위젯 트리에 알리고, 구독된 위젯들은 다시 리빌드됩니다.

즉, Provider에서 구독 연결은 위젯 트리 탐색(BuildContext가 필수) → 특정 Provider 찾기 → 이 Provider를 구독하는 과정입니다

Riverpod의 ref.watch,read

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

// 1. 프로바이더 선언 (상태 관리용)
final counterProvider = StateProvider<int>((ref) => 0);

void main() {
  // 2. ProviderScope로 앱 전체 감싸기: riverpod 상태 관리 시작점
  runApp(
    ProviderScope(
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CounterScreen(),
    );
  }
}

class CounterScreen extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // 3. 상태값 읽기
    final count = ref.watch(counterProvider).state;

    return Scaffold(
      appBar: AppBar(title: Text('Riverpod 예제')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('현재 카운터 값: $count', style: TextStyle(fontSize: 24)),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                // 4. 상태 업데이트
                ref.read(counterProvider).state++;
              },
              child: Text('카운터 증가'),
            ),
          ],
        ),
      ),
    );
  }
}

 

Riverpod은 앱 최상위에 ProviderScope를 위젯으로 감싸서 상태 관리 환경을 준비하는데

위젯트리와 완전히 독립된 상태 저장소 ProviderContainer를 가진다. ( 기록형 )

 

  1. ref.watch(provider) 호출 시, ref는 자신이 속한 빌드(빌드 함수 실행 컨텍스트)를 알아서, 빌드 내에서 이 provider를 구독한다.라는 정보를 내부에 저장합니다.
  2. 다시 말해, Riverpod은 빌드를 하는 위젯 위치를 직접 탐색하지 않고, ref가 자신이 어떤 provider를 구독하는지 별도의 내부 데이터 구조로 기록합니다.
  3. 상태가 변경되면 ProviderContainer가 등록된 BuildContext에게 알려, 해당 위젯의 build() 재실행 요청이 이루어집니다

즉, Riverpod에서는 구독 관계가 ref 내부 데이터 구조에 저장되고, 실제 상태 변경 시 Container가 이 기록을 보고 관련 빌드 함수를 호출하는 방식

내가 지금 빌드 중이고, 어떤 provider를 쓰는지만 처음에 기록해두고,
상태 바뀌면 그 기록을 바탕으로 '넌 이 provider를 쓰니까 다시 빌드하라'고 알려줌

 

'Flutter > CS' 카테고리의 다른 글

Lazy Loading & ListView.builder  (0) 2025.08.12
Flutter Tree & Hot Reload  (0) 2025.08.12