setState() or markNeedsBuild() called during build
에러의 원인
정진규 Software Engineer 노션에 따르면 마치 Null Pointer Exception과 같은 광범위한 에러이다. 따라서 에러가 발생하는 시점에 관한 코드를 자세히 살펴보는 것이 좋다. 에러의 원인은 말 그대로 UI를 이미 빌드하고 있는데 해당 UI가 구독하고 있는 state에 변경이 일어나서 또 변경하게 생겼다는 것이다.
setState() or markNeedsBuild() called during build
에러 원인 분석
나의 경우에는 TestPage에 진입을 시도할 때마다 해당 에러가 발생하였다. 따라서 TestPage를 살펴보았다. TestPage는 TestState의 Consumer로서 TestState에 변경이 일어나면 rebuild를 하게 되어있다. 그런데 build()
부분에는 testState에 변경을 가하는 부분을 찾아볼 수 없었고, state를 읽어오는 부분 밖에 없었다.
진입을 시도할 때마다 해당 에러가 발생하는 점 때문에 TestPage initState()
를 주목하였다. 그랬더니 아래 코드와 같이 UI를 빌드하는 코드에서 ChangeNotifier인 TestState class를 건드리고 있었다. ( testState.startNewTest()
부분)
@override
void initState() {
super.initState();
final testState = context.read<TestState>();
audioTimer = testState.audioTimer;
testState.startNewTest();
// 퀴즈 종료 시 이동할 화면 설정
testState.setOnTestEnd(() {
if (mounted) {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const EndingPage()),
);
}
});
}
즉, initState()가 실행된 다음에 build()가 실행되는데, initState()에 들어있는 testState.startNew()가 내부적으로 notifyListener()를 트리거하게 되고, build()가 UI를 그리고 있는 와중에 이 변경을 감지하면 이를 막기 위해 flutter가 setState() or markNeedsBuild() called during build
에러를 발생시키는 것이다.
setState() or markNeedsBuild() called during build
에러 해결
build()가 모두 완료된 후에 상태변경을 보장할 수 있도록 addPostFrameCallback
를 사용한다.
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
final testState = context.read<TestState>();
audioTimer = testState.audioTimer;
testState.startNewTest();
// 퀴즈 종료 시 이동할 화면 설정
testState.setOnTestEnd(() {
if (mounted) {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const EndingPage()),
);
}
});
});
}
'Flutter' 카테고리의 다른 글
Flutter 앱 서명하는 법 (0) | 2025.04.16 |
---|---|
Consider canceling any active work during "dispose" or using the "mounted" getter to determine if the State is still active. 에러 원인과 해결 방법 (0) | 2025.03.20 |
Flutter UI와 State의 분리 - @initState와 Callback 함수 사용 (0) | 2025.03.16 |
Unbounded height에 대한 이해 (0) | 2025.02.02 |
새로운 flutter 프로젝트 생성하는 법 (1) | 2025.01.07 |