두 탭 간 상태 공유를 어떻게 할 수 있냐
BroadcastChannel API
상황
교육 플랫폼을 개발하던 중 이런 상황이 생겼다.
커리큘럼 상세 페이지에는 행동 유형 검사 카드가 있고, 카드를 클릭하면 window.open()으로 새 탭에서 채팅 형식의 검사가 시작된다. 검사가 끝나면 원래 탭의 카드가 완료 상태로 바뀌어야 했다.
두 탭은 서로 독립적으로 열려 있기 때문에, 한 탭의 상태 변경을 다른 탭에 전달할 방법이 필요했다.
BroadcastChannel로 문제를 해결해보자
그렇다면 어떻게 탭 간 상태 공유를 가능케 할까.
BroadcastChannel은 같은 origin을 공유하는 브라우저 탭 사이에서 메시지를 주고받을 수 있는 Web API다. 채널 이름이 공유 식별자 역할을 하기 때문에, 탭의 참조나 URL을 몰라도 같은 이름으로 채널을 열기만 하면 브라우저가 자동으로 같은 버스에 연결해준다.
구현 코드
검사 탭 — 완료 시 메시지 송신
const handleEndTest = () => {
const channel = new BroadcastChannel("interest-test");
channel.postMessage({ type: "completed", curriculumId });
channel.close(); // 한 번 쓰고 닫기
};
원래 탭 — 메시지 수신 후 상태 업데이트
useEffect(() => {
const channel = new BroadcastChannel("interest-test"); // 같은 이름으로 연결
channel.onmessage = (e) => {
// e.data에 postMessage()로 넘긴 객체가 그대로 들어온다
if (e.data?.type === "completed" && e.data?.curriculumId === curriculumId) {
setIsBehavioralTestCompleted(true);
}
};
return () => channel.close(); // cleanup
}, [curriculumId]);
주의사항
- 지속성 없음 — BroadcastChannel은 in-memory 기반이므로 수신한 메시지는 브라우저 메모리에만 존재하고 별도로 저장되지 않는다.
- 같은 origin만 — 다른 도메인 간에는 동작하지 않는다.
- 사용 후 close() — 채널은 GC되지 않으므로 반드시 닫아줘야 한다.