인프런 커뮤니티 질문&답변

gslee100님의 프로필 이미지
gslee100

작성한 질문수

Flutter 앱 개발 실전

Tile

Lang Tile

해결된 질문

작성

·

185

1

Tile(
  icon: 'language',
  title: S.current.language,
  subTitle: IntlHelper.isKo ? S.current.ko : S.current.en,
  onPressed: () => langService.toggleLang(),
)

안녕하세요.

강의 정말 큰 도움이 되고 있습니다!

Lang Tile 구현에서 onPressed 콜백에서 context.watch<LangService>().toggleLang() 으로 쓰면 왜 에러가 나는건가요,,??(아래와 같은 에러가 발생합니다..)


Tried to listen to a value exposed with provider, from outside of the widget tree.

This is likely caused by an event handler (like a button's onPressed) that called

Provider.of without passing listen: false.

To fix, write:

Provider.of<LangService>(context, listen: false);

It is unsupported because may pointlessly rebuild the widget associated to the

event handler, when the widget tree doesn't care about the value.

The context used was: SettingBottomSheet(dependencies: [_InheritedProviderScope<LangService?>, _InheritedProviderScope<ThemeService?>])

'package:provider/src/provider.dart':

Failed assertion: line 274 pos 7: 'context.owner!.debugBuilding ||

listen == false ||

debugIsInInheritedProviderUpdate'

답변 2

1

DevStory님의 프로필 이미지
DevStory
지식공유자

안녕하세요.

아래와 같이 실행 했을 때 질문 주신 에러가 발생하셨을 겁니다.

Tile(
  onPressed: () => context.watch<LangService>().toggleLang(),
),

Provider 패키지의 context.watch<LangService>LangService에 변경사항이 있을 때 BuildContext가 소속된 위젯을 다시 빌드하여 화면을 갱신하도록 등록하는 과정이 포함되어 있습니다.

소스 코드상의 주석에서도 확인할 수 있듯 watch는 위젯의 Build() 함수 내부에서만 사용 가능하며, 그렇지 않은 경우 첨부해주신 에러가 발생합니다.

 

위젯의 Build() 함수 이외의 영역에서 조상 위젯에 접근하고 싶으신 경우 LangService에 접근하고 싶으신 경우 변경 사항을 청취하지 않는 context.read()를 사용하여 접근하시거나, 익명 함수를 없이 함수 자체를 넘기시면 정상적으로 작동합니다.

/// onPressed에 익명 함수를 삭제하신 뒤, toggleLang 함수 자체를 아래와 같이 넘겨주시면 정상 작동
Tile(
  onPressed: context.watch<LangService>().toggleLang,
),
/// context.read로 접근하면 정상 작동
Tile(
  onPressed: () => context.read<LangService>().toggleLang(),
),

감사합니다 :)

0

안녕하세요, 인프런 AI 인턴입니다. gslee100님.

질문하신 내용과 관련하여 LangService 객체를 context.watch를 사용하여 바라보려고 할 때 발생하는 에러에 대한 지식공유자님의 기존 답변을 찾았습니다. 해당 질문의 주된 내용은 context.watch 메소드를 사용할 때 발생하는 에러와 provider 패키지의 사용 방법에 대한 것입니다.

이와 관련하여, Flutter에서 Provider 패키지를 사용할 때 어떤 이벤트 핸들러(예: 버튼의 onPressed 콜백) 안에서 Provider.of()를 호출할 때 ‘listen’ 매개변수를 false로 설정하지 않으면 발생할 수 있는 에러에 대한 설명이 담긴 답변 링크를 첨부해드립니다. 이러한 에러를 방지하기 위해서는 이벤트 핸들러 내부에서 Provider.of<LangService>(context, listen: false) 코드를 사용하여 명시적으로 값을 듣지 않도록 설정해야 합니다. 이 경우, 위젯 트리가 값에 대해 걱정하지 않는 상황에서도 위젯이 불필요하게 다시 빌드되는 것을 방지할 수 있습니다.

아래는 유사한 문제에 대한 기존 답변 링크입니다:

  • 섹션3 - Tile 강의 질문
    • SettingBottomSheet에서 ThemeServices는 context.read를 사용해서 호출해도 되고, LangService는 context.watch로 호출해야 하는 이유를 설명하고 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

gslee100님의 프로필 이미지
gslee100

작성한 질문수

질문하기