[Flutter] BuildContext 이해하기

ryan·2021년 9월 2일
1

Dart/Flutter

목록 보기
18/21
post-thumbnail

링크

// error
Scaffold.of() called with a context that does not contain a Scaffold

BuildContext

  1. "A handle to the location of a widget in the widget tree."
    => "widget tree에서 현재 widget의 위치를 알 수 있는 정보"
int addNumber(int a, int b) {
	return a+b;
}
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'appBar',
      theme: ThemeData(primarySwatch: Colors.amber),
      home: MyPage(),
    );
  }
}

class MyPage extends StatelessWidget {
  @override
  // build라는 함수명 앞에 Widget은 타입이다.
  // 즉, build 메서드는 Widget 타입니다.
  // 그리고 build 메서드에 들어오는 인자값은
  // BuildContext라는 타입의 context라는 인자값이라는 의미이다.
  Widget build(BuildContext context) {
    // 즉, build 함수는 context라는 인자값을 대입한,
    // Scaffold라는 위젯을 리턴한다는 의미이다
    return Scaffold(
      appBar: AppBar(
        title: Text('Appbar icon menu'),
        centerTitle: true,
        elevation: 0.0,
        actions: [
          IconButton(
            icon: Icon(Icons.shopping_cart),
            onPressed: () {
              print('Shopping cart button is clicked');
            },
          ),
          IconButton(
            icon: Icon(Icons.search),
            onPressed: () {
              print('Search button is clicked');
            },
          ),
        ],
      ),
     // ...
    );
  }
}

build 함수는 Scaffold라는 위젯을 리턴하는데, 이 때의 위젯 트리상에서 어디에 위치하는가에 대한 정보를 가지고 있는 context라는 정보를 넣어서 리턴을 해준다는 의미이다.

  1. "Each widget has its own BuildContext, which becomes the parent of the widget returned by the StatelessWidget.build or State.build function."
    => "이 BuildContext는 stateless위젯이나 state 빌드 메서드에 의해서 리턴 된 위젯의 부모가 된다"
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'appBar',
      theme: ThemeData(primarySwatch: Colors.amber),
      home: MyPage(),
    );
  }
}

// StatelessWidget으로 만든 MyPage라는 커스텀 위젯 생성.
class MyPage extends StatelessWidget {
  @override
// MyPage라는 커스텀 위젯도 자신만의 BuildContext 타입의 context를 가지고 있다.
  Widget build(BuildContext context) {
    // 이제 이곳에서 build 메서드를 통해서 Scaffold 위젯이 리턴이 되고,
    // Scaffold 위젯은 부모인 MyPage의 context를 그대로 물려받게 된다.

    // 그렇다면 만약 어떤 필요에 의해서 위젯 트리상에서 Scaffold 위젯의 위치가 필요하다면, 현재 Scaffold 위젯의 context를 참조하면 어떻게 될까?
    // 그러면 아래와 같은 에러를 보게 됩니다
    // "Scaffold.of() called with a context that does not contain a Scaffold"
    // BuildContext 사용이 까다로운 이유가 여기에 있다.
    // Scaffold 위젯이 존재하고 있으니, 당연히 현재 Scaffold 위젯이 위젯 트리 상에서
    // 어디에 위치하고 있는지를 알기 위해서 Scaffold 위젯을 가지고 있는 context를 참조하는 것이 상식적으로 마땅한데!
    // 정작 Scaffold 위젯의 context는 위젯트리 내에서 Scaffold가 어디에 위치하고 있는지에 대한 정보를 전혀 가지고 있기않기때문이다
    return Scaffold(
      appBar: AppBar(
        title: Text('Appbar icon menu'),
        centerTitle: true,
        elevation: 0.0,
        actions: [
          IconButton(
            icon: Icon(Icons.shopping_cart),
            onPressed: () {
              print('Shopping cart button is clicked');
            },
          ),
          IconButton(
            icon: Icon(Icons.search),
            onPressed: () {
              print('Search button is clicked');
            },
          ),
        ],
      ),
      // ...
    );
  }
}

Scaffold.of() called with a context that does not contain a Scaffold 에러를 어떻게 해결해야할까?

build 메서드에 의해서 리턴된 Scaffold 위젯은 그 부모의 BuildContext 타입의 context를 그대로 물려받는다고 했으니, Scaffold 위젯 밑에서 build 메서드로 무언가 위젯을 리턴하면 그 위젯은 부모인 Scaffold 위젯의 진짜 context를 물려받을 수 있을 것이다.

profile
👨🏻‍💻☕️ 🎹🎵 🐰🎶 🛫📷

0개의 댓글