본문 바로가기

Frontend

React-Arborist 트리 UI에서 Input 포커스 문제 해결

트리 UI를 react-arborist로 만들다가 노드 이름을 수정하는 input을 띄웠을 때, 입력이 제대로 안 되는 문제를 겪었다. 한 글자를 입력하면 input에서 focus가 해제되어 더 이상 입력이 불가능했다.

 

처음에는 ref와 useEffect를 써서 focus()를 강제로 주는 방식으로 해결하려 했지만, 입력이 시작되면 곧바로 트리의 selection 로직이 개입해 다시 focus가 다른 곳으로 이동해 버렸다.즉, 사용자가 글자를 입력 → onChange 발생 → setDraftName() 실행 → React는 상태가 변했으니 해당 노드 컴포넌트를 다시 렌더링 → 이때 트리 내부 selection 관리 로직도 같이 실행되면서 이 노드는 여전히 선택된 상태임을 갱신하거나 selection을 유지하기 위해 다시 focus를 노드 컨테이너 쪽에 줘버린다.

그 결과, input이 활성화 되어 있어도 매번 다시 클릭해야 했고, 연속 입력이 불가능했다.

 

해결 방법: autoFocus

해결 방법은 의외로 단순했다. input에 autoFocus 속성을 추가하자 문제가 해결됐다.

<Input
  autoFocus={true}
  inputRef={inputRef}
  value={draftName}
  onChange={(e) => setDraftName(e.target.value)}
  onClick={(e) => e.stopPropagation()}
  onKeyDown={(e) => {
    if (e.key === 'Enter') {
      e.preventDefault();
      commitEdit();
    }
  }}
  size="small"
  placeholder="이름 입력"
/>

 

autoFocus는 브라우저가 DOM에 input을 렌더링하는 순간 자동으로 focus를 주는 HTML 표준 속성이다. React에서 autoFocus를 사용하면, React의 렌더링 사이클이나 외부 라이브러리 로직이 개입하기 전에 브라우저가 직접 input에 focus를 넣어준다.

 

autoFocus는 매 리렌더가 아니라 마운트 될 때만 동작한다. 즉, 요소가 DOM에 새로 마운트될 때 한 번 포커스를 준다. 그래서 같은 input이 유지된 채로 값만 바뀌며 리렌더되는 상황이라면 autoFocus는 다시 실행되지 않는다. 하지만, 나의 경우에는 한 글자 입력 → selection 로직 개입 → blur 발생이 반복 되었기 때문에 autoFocus가 필요했던 것이다.