개발(Development)/React(리액트)
[React] useRef로 DOM 취득시, null | undefined 되는 이유와 해결방법
카레유
2022. 8. 9. 13:53
# useRef : DOM 취득시 null이 되는 이유
useRef로 DOM을 취득시,
사용 시점에 따라 null 이나 undefined가 될 수 있다.
예를 들어 아래 코드는 작동하지 않는다.
import React, { useEffect, useRef } from 'react';
import './App.css';
function App() {
// useRef 사용
const inputRef = useRef(null);
// 최초 실행시 input에 focus 주기: 실패한다.
inputRef.current.focus();
console.log(inputRef.current); // null 이 찍힌다.
return (
<div className="App">
{/* input 을 useRef로 참조 */}
<input ref={inputRef}></input>
</div>
);
}
export default App;
주로 최초 렌더링 시,
컴포넌트 함수 구현부에서 useRef로 DOM을 취득하고,
바로 ref.current 로 참조하여 사용할 때 null이 되는 경우가 많다.
왜냐하면,
아직 return 부분이 실행되지 않아서, 실제 DOM에 반영되지 않았는데 참조하려 하기 때문이다.
즉, 컴포넌트함수의 return 부분이 호출되어 실제 DOM에 반영되어야만 DOM 취득이 가능하다.
컴포넌트 렌더링 과정은 아래 글을 참고하자.
[React] 컴포넌트 렌더링 과정 정리(useLayoutEffect vs. useEffect)
# useRef : 안전한 사용 방법
1. didMount 되어 DOM에 반영된 이후 사용하자.
- 최초에는 didMount 직후 호출되는 useEffect 에서 사용하는게 안전하다.
- 이후 업데이트 재렌더링시에는 이미 DOM에 반영된걸 참조하므로 어디서나 사용 가능하다.
2. 항상 유효성 체크후 사용하자.
- 조건부 렌더링 등에 의해, 컴포넌트가 Unmount 되는 경우에도 null이 될 수 있다.
- 따라서 if 문이나 단축평가를 이용해 유효성 검사 후에 사용하는게 안전하다.
import React, { useRef, useEffect } from "react";
export default function App() {
// 최초 렌더링 시, DOM이 생성되지 않아 null 이다.
const inputRef = useRef();
// 실제 DOM에 반영된 이후, DOM취득 가능
useEffect(() => {
// ref는 항상 존재여부를 검사하고 사용해야 한다(단축평가 Good!)
inputRef.current && inputRef.current.focus();
});
return (
<div>
<input ref={inputRef} type="text"></input>
</div>
);
}