채팅창 렌더링 최적화

🚨 문제 상황

마클에서 준일님이 시연하시던 중에 채팅창 외부를 눌렀음에도 채팅창이 계속 리렌더링되는 이슈

0image.png

개선…해야겠지?

🏃 해결 과정

리액트 개발자 도구는 알고만 있었지 써보지는 않았는데 왜 이제 써봤을까 싶음

렌더링에 걸린 속도와 해당 컴포넌트를 바로 확인해볼 수 있다.

1image.png

채팅창에서 헤더의 설정 버튼을 누른 상태에서 헤더를 제외한 외부를 누르면 팝업이 닫아지도록 이벤트 설정을 해둠

→ 이로인해 채팅창 클릭시 매번 불필요한 리렌더링이 발생하고 있었음

typescript
  const handleClickOutside = useCallback(
    (event: MouseEvent) => {
      if (headerRef.current && !headerRef.current.contains(event.target as Node)) {
        dispatch({ type: 'CLOSE_SETTINGS' });
      }
    },
    [dispatch]
  );

handleClickOutside 함수의 dispatch 호출로 인해 이미 state.isSettingsOpenfalse인 상태에서도 CLOSE_SETTINGS 액션이 계속 발생하면서 불필요한 리렌더링이 발생했음

따라서 현재 상태를 확인한 후 필요할 때만 dispatch를 호출하도록 조건을 추가함

✅ 문제 해결

typescript
  const handleClickOutside = useCallback(
    (event: MouseEvent) => {
      if (headerRef.current && !headerRef.current.contains(event.target as Node) && state.isSettingsOpen) {
        dispatch({ type: 'CLOSE_SETTINGS' });
      }
    },
    [dispatch, state.isSettingsOpen]
  );

  • state.isSettingsOpen 확인 추가

    state.isSettingsOpentrue인 경우에만 dispatch를 호출하도록 조건을 추가

    → 닫혀있는 상태에서는 불필요한 dispatch 호출 방지

  • state.isSettingsOpen useCallback의 의존성에 추가

    state.isSettingsOpen 값을 기반으로 조건을 추가했으므로, 이를 useCallback의 의존성 배열에 포함해 최신 상태 값을 항상 반영하도록 보장