click후 blur를 처리하는 방법

hyeondoonge·2021년 10월 5일
2

식별된 문제

TextField가 focus되면 관련 데이터 리스트가 렌더링되고
리스트 중 아이템 하나를 click한 후 blur이벤트가 처리되도록 해야하는데
blur이벤트가 먼저 처리되는 문제를 발견했다.

첫 번째 시도

아래 코드를 실행했을때 내가 바라는 이벤트 발생 순서는 click이벤트 -> blur이벤트인데
실제로 수행해보니 blur이벤트가 먼저 발생했다.
이후 click이벤트를 가진 아이템들이 사라져 예상치 못한 문제를 식별하게됐다.

	<div
          onBlur={(event) => {
            listRef.current.style.display = 'none';
            if (!languageItems.map(({ name }) => name).includes(language)) {
              alertRef.current.style.opacity = 1;
            }
          }}
        >
          <TextField
            name="language"
            label="언어"
            onChange={onChangeLanguage}
          />
        </div>
        <div>
          {languageItems.length > 0 && (
            <ul
              ref={listRef}
              onClick={onClickLanguage}
            >
              {languageItems.map(({ _id, name }) => (
                <li key={_id}>{name}</li>
              ))}
            </ul>
          )}
        </div>

왜 Blur이벤트가 Click이벤트 보다 먼저 처리가되는지를 알아내면 이 문제를 해결할 수 있을 것 같았다.

두 번째 시도

나와 같은 문제를 겪은 다른 이들의 글을 찾아보며 해결을 하게됐다.
왼쪽 마우스 버튼을 누를 시 일어날 수 있는 이벤트는
mouseDown, mouseUp, click으로 세 가지가 있고
blur이벤트까지 포함해 mouseDown -> blur -> mouseUp -> click 순서로 일어난다.

마우스 이벤트 중 blur전에 일어나는 이벤트는 mouseDown임을 이해할 수 있었다.

당연히 mouseDown != click 이기 때문에 click한 시점의 값이 mouseDown할 때의 값과 다를 수 있다.
제목에서처럼 'click후 blur를 처리하는 방법'를 완벽히 해결했다고는 볼 수 없지만 😅;;;
내가 맞이한 이슈는 click 이벤트 대신 mousedown 이벤트를 처리해서 해결했다.

비슷한 문제를 겪은 이들에게 하나의 해결책이 될 수 있을 것 같다!

3개의 댓글

comment-user-thumbnail
2023년 5월 12일

감사합니다.. 금요일.. 야근을 할 뻔 했지만 덕분에 광명 찾고 퇴근합니다.

1개의 답글