input 태그의 focus() 실행 시 아무런 일도 일어나지 않음..
setTimeout 내부에서 focus를 실행시키니 제대로 동작한다.
useEffect(() => {
if (el.isSelect) {
setTimeout(() => {
if (inputRef.current === null) return;
inputRef.current.focus();
}, 0);
}
}, [el.isSelect])
이유를 찾아보니 DOM 요소가 연결되기 전에 DOM 요소에 접근하려하면 제대로 동작하지 않는다고 한다.
그런데 이미 mount되고 난 훨씬 뒤인데??
의문이 들어 좀 더 자세히 찾아봤다.
Github Copilot
DOM에 연결하는 작업은 주로 컴포넌트가 처음 마운트(mount)될 때 발생합니다. 이는 React에서 ref 객체를 사용하여 DOM 요소에 접근할 때 특히 중요합니다. ref 객체는 컴포넌트가 마운트되고 해당 DOM 요소가 렌더링된 후에만 접근 가능합니다.
그러나 React는 효율적인 렌더링을 위해 여러 가지 최적화 기법을 사용합니다. 이로 인해 컴포넌트의 상태가 변경되어도 실제 DOM 업데이트는 비동기적으로 이루어질 수 있습니다. 따라서 ref를 사용하여 DOM 요소에 접근하려면 해당 DOM 요소가 실제로 업데이트된 후에 접근해야 합니다.
이러한 이유로 setTimeout을 사용하여 focus() 메서드를 호출하는 코드를 다음 이벤트 루프 틱으로 연기하는 것입니다. 이렇게 하면 inputRef.current가 실제로 DOM에 연결된 후에 focus() 메서드를 호출할 수 있습니다.
따라서, DOM에 연결하는 작업은 주로 컴포넌트가 마운트될 때 발생하지만, 비동기적인 DOM 업데이트로 인해 ref를 사용하여 DOM 요소에 접근할 때는 실제 DOM 업데이트가 완료된 후에 접근해야 합니다.
그렇다고 한다.
'🦈 react' 카테고리의 다른 글
[React로 화이트보드] 상태 변경 시 Canvas 업데이트 (0) | 2024.02.02 |
---|---|
[React로 화이트보드] React에서 Canvas로 선그리기 (0) | 2024.01.09 |
[React로 화이트보드] TypeScript + Tailwindcss 개발환경 셋팅 (2) | 2024.01.06 |
[React로 테트리스] Redux-toolkit으로 전역상태 관리하기 (0) | 2023.12.28 |
[React로 테트리스] Event Handler로 State 처리하기 (0) | 2023.12.26 |