Flutter에서 Bloc 패턴을 사용할 때, 스트림을 다룰 일이 많다. 이 과정에서 forEach와 onEach라는 두 가지 메서드를 사용하게 되는데 처음에는 둘의 차이를 잘 몰랐다가 이번기회에 두 메서드의 차이점을 정리해보았다. 차이점을 알아보기전에 먼저 공통점부터 알아보자
1. 공통점
✅ 스트림(Stream) 기반의 데이터 처리
forEach와 onEach는 모두 스트림에서 데이터를 받아 처리하는 메서드이다. 따라서, Stream을 활용하는 비동기 로직에서 주로 사용된다.
✅ emit()을 활용한 상태 관리 가능
두 메서드 모두 emit()을 통해 Bloc의 상태를 업데이트하는 것이 가능하다. (하지만 onEach에서는 상태 변경이 기본적으로 이루어지지 않으며, forEach는 상태 변경을 자동으로 처리한다. 자세한건 이후 차이점에서 다룸)
✅ onError 핸들링 지원
두 메서드 모두 에러 발생 시 onError 콜백을 제공하여 예외를 처리할 수 있다. 이를 통해 예기치 않은 에러가 발생했을 때 적절한 대응을 할 수 있다.
2. 차이점
Bloc 메인테이너 feleangel은 두 메서드의 차이에 대해 위와 같이 언급하고 있는데 이를 정리하면 아래와 같다.
1. forEach의 onData는 상태(state)를 반환한다.
2. onEach의 onData는 단순히 실행되는 함수이고, 반환값이 없다 (void).
3. forEach는 스트림 데이터를 Bloc 상태로 변환하여 emit()하는 데 사용해야 한다.
4. onEach는 상태를 바꾸지 않고, 로그 출력, API 호출 등의 부가적인 작업을 할 때 사용해야 한다.
역할 | 스트림 데이터를 받아 상태 변경 | 스트림 데이터를 받아 부가적인 작업 수행 |
상태 변화 | ✅ 있음 (emit()을 자동 호출) | ❌ 없음 (직접 emit()을 호출하지 않음) |
UI 업데이트 | ✅ 새로운 데이터를 받아 UI 업데이트 가능 | ❌ UI 업데이트가 자동으로 이루어지지 않음 |
불변성 유지 | ⚠️ 기존 상태를 복사하여 변경해야 함 | ✅ 상태 변경이 없으므로 안전함 |
사용 예시 | 실시간 UI 업데이트 (채팅, 카운터 등) | 로그 기록, API 호출, 푸시 알림 |
3. 예제를 통해 알아보기
https://gist.github.com/suojae/999e82fb2454bbaf2d134352fd3ed42a
bloc_foreach.dart
GitHub Gist: instantly share code, notes, and snippets.
gist.github.com
예제를 통해 좀더 직관적으로 차이를 이해할 수 있다. 위코드에서 onEach를 실행하면 로그를 통해 스트림 값의 변화를 알 수 있지만 근본적인 상태값(Counter)은 변하지 않는다는 것을 알 수 있다. 하지만 forEach를 탭하면 직접적인 상태를 변경해 방출하는 것을 확인할 수 있다.
4. 그래서 언제 어떤 함수를 써야할까?
✅ onEach를 사용하는 것이 좋은 경우
- 상태 변경 없이 부가적인 작업(로그, 분석, API 호출)만 수행해야 할 때
- 스트림 데이터가 많지만, 상태 변경 없이 감시만 하고 싶을 때
- 불변성을 유지해야 하는 상황에서 안전한 스트림 핸들링이 필요할 때
✅ forEach를 사용하는 것이 좋은 경우
- 스트림 데이터를 받아 UI를 업데이트해야 할 때
- 실시간 데이터를 반영해야 하는 경우 (채팅, 카운터, 네트워크 요청 결과 등)
- 새로운 데이터를 받아 상태를 변경하고, 이를 기반으로 비즈니스 로직을 수행할 때
아무래도 스트림을 쓰는 대부분의 상황은 실시간 데이터를 반영하는 경우이기 때문에 forEach를 쓰는 경우가 많을 것 같다 :)
'Flutter' 카테고리의 다른 글
Flutter에서 드롭다운 메뉴 구현하기 (0) | 2025.03.07 |
---|---|
하단버튼 키보드가 가리지 않게 이동시키기 (0) | 2025.03.05 |
플러터에 지역화 기능 넣어주는 방법 (1) | 2025.03.03 |
다른 ios 계정 프로젝트에 내 아이폰 기기 등록하기 (0) | 2025.03.01 |
외부 탭할시 키보드는 내려가는데 텍스트필드 포커싱 해제가 안되었던 이슈 (0) | 2025.02.28 |