본문 바로가기
Frontend

React input 포커스 풀림: key 관리

by 미래 감자 2025. 8. 27.

React에서 리스트를 렌더링할 때 key를 부여하는 건 필수적이다. 종종 input 요소를 map으로 뿌려야하는 경우가 있는데 이때 key를 nanoid()와 같은 랜덤한 고유값으로 주면 한 글자 입력 시 포커스가 풀리는 현상이 발생한다.

 

한 글자 입력 시 input focus 사라짐 현상


 

🔍  발생 원인

React에서 map으로 요소를 렌더링할 때 nanoid()를 사용하면 충돌 가능성이 없는 고유한 key를 쉽게 부여할 수 있다. 하지만 nanoid()는 호출할 때마다 새로운 key를 생성하기 때문에, input을 map으로 뿌릴 때 매번 key가 바뀌게 된다. 이 경우 React는 기존 DOM을 재사용하지 않고 새로운 DOM으로 인식해 다시 그리게 되므로, 입력 중이던 값이나 포커스가 사라지는 문제가 발생한다.

 

즉, 해당 현상은 map 때문이 아니라 unstable key 값으로 인해 발생한다.

 

✅ 해결 방법

1. 데이터에 있는 고유 id 사용

리스트 아이템이 DB id와 같은 고유 식별자를 갖고 있다면 그것을 key로 사용하는 것이 가장 이상적인 해결 방법이다.

{items.map((item) => (
  <input key={item.id} value={item.value} />
))}

 

2. 초기화 시 한 번만 nanoid 생성

만일 아이템에 id가 없다면, 컴포넌트 초기 렌더링 시에 한 번만 nanoid를 만들어 상태에 저장한 뒤 사용할 수 있다.

const [inputs, setInputs] = useState(
  Array.from({ length: 3 }, () => ({ id: nanoid(), value: '' }))
);

return (
  <div>
    {inputs.map((item) => (
      <input key={item.id} value={item.value} />
    ))}
  </div>
);

 

stable한 key 값 부여 시 focus 풀림 해결


 

해당 현상이 발생하는 문제의 본질은 map 사용 여부가 아니라 key의 안정성(stability)에 있다.
key 값이 매번 바뀌게 되면 React는 해당 요소를 이전과 동일한 노드로 인식하지 않고, 새로운 노드로 판단하여 기존 DOM을 제거하고 새로 생성한다. 그 결과 input에 주어져 있던 포커스가 풀리게 되는 것이다.
따라서 리렌더링이 발생하더라도 변하지 않는 안정적인 key를 부여하는 것이 중요하다.