일반 HTML DOM 요소에 이름 달 때는 id를 사용하는데, 특정 DOM에 접근할 때 아래와 같은 방식을 사용한다
document.getElementById("element");
위의 방법을 react에 적용하면 DOM을 랜더링할 때 전역적으로 적용되고, unique 하게 사용되지 않을 수도 있기 때문에 특수한 경우가 아니면 사용을 권장하고 있지 않다
이의 대안으로 ref(reference)가 나왔고, ref를 사용하면 컴포넌트 내부에서만 작동하기 때문에 이런 문제가 발생하지 않는다
단 ref는 DOM을 직접적으로 건드려야 할 때 사용해야 한다
import "../App.css";
import React, { useRef, useState } from "react";
const RefExample = (): JSX.Element => {
const [value, setValue] = useState<string>("");
const [validate, setValidate] = useState<boolean>(false);
const inputRef = useRef<HTMLInputElement>(null);
const onhandleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setValue(e.target.value);
}
const onhandleClick = () => {
setValidate(value === "0000");
inputRef.current?.focus();
}
return (
<div>
<input type="password" value={value} onChange={onhandleChange} ref={inputRef} className={validate ? "success" : "failure"} />
<button onClick={onhandleClick}>검증하기</button>
</div>
);
};
export default RefExample;
button을 클릭할 때 input DOM에 focus를 주도록 하는 샘플 소스이다
컴포넌트에도 직접 ref를 달 수 있고, 이 경우에는 컴포넌트 내부에 있는 DOM을 컴포넌트 외부에서 사용할 때 쓴다
여기서 오해하지 말아야할 점은 ref는 데이터 교류를 할 때 사용한다고 이해하면 잘못된 것이다
가능은 하겠지만 그런 방식으로 사용하면 리액트 사상에 어긋난 설계이므로 ref는 가급적 컴포넌트 내에서 DOM을 직접 조작해야 하는 일이 있을 때만 사용하도록 하자