[리액트] 함수형 컴포넌트에서 ref를 사용할 때에는 useRef라는 Hook함수를 사용. / 클래스형 컴포넌트에서는 콜백함수 of React.createRef라는 함수를 사용.
// JavaScript 를 사용 할 때에는,
// 우리가 특정 DOM 을 선택해야 하는 상황에 getElementById, querySelector 같은 DOM Selector 함수를 사용해서 DOM 을 선택합니다.
// 리액트를 사용하는 프로젝트에서도 가끔씩 DOM 을 직접 선택해야 하는 상황이 발생 할 때도 있습니다.
// 예를 들어서 특정 엘리먼트의 크기를 가져와야 한다던지, 스크롤바 위치를 가져오거나 설정해야된다던지, 또는 포커스를 설정해줘야된다던지 등
// 추가적으로 Video.js, JWPlayer 같은 HTML5 Video 관련 라이브러리, 또는 D3, chart.js 같은 그래프 관련 라이브러리 등의 외부 라이브러리를 사용해야 할 때에도 특정 DOM 에다 적용하기 때문에 DOM 을 선택해야 하는 상황이 발생
// 함수형 컴포넌트에서 ref 를 사용 할 때에는 useRef 라는 Hook 함수를 사용합니다.
// 클래스형 컴포넌트에서는 콜백 함수를 사용하거나 React.createRef 라는 함수를 사용
function InputSample() {
const [inputs, setInputs] = useState({
name: "",
nickname: "",
});
const nameInput = useRef();
const { name, nickname } = inputs; // 비구조화 할당을 통해 값 추출
const onChange = (e) => {
const { value, name } = e.target; // 우선 e.target 에서 name 과 value 를 추출
setInputs({
...inputs, // 기존의 input 객체를 복사한 뒤
[name]: value, // name 키를 가진 값을 value 로 설정
});
};
const onReset = () => {
setInputs({
name: "",
nickname: "",
});
nameInput.current.focus();
};
return (
<div>
<input
name="name"
placeholder="이름"
onChange={onChange}
value={name}
ref={nameInput}
/>
<input
name="nickname"
placeholder="닉네임"
onChange={onChange}
value={nickname}
/>
<button onClick={onReset}>초기화</button>
<div>
<b>값: </b>
{name} ({nickname})
</div>
</div>
);
}
export default InputSample;
컴포넌트에서 특정 DOM 을 선택해야 할 때, ref 를 사용해야 한다고 배웠었습니다. 그리고, 함수형 컴포넌트에서 이를 설정 할 때 useRef 를 사용하여 설정한다고 배웠었습니다.
useRef Hook 은 DOM 을 선택하는 용도 외에도, 다른 용도가 한가지 더 있는데요,
바로, 컴포넌트 안에서 조회 및 수정 할 수 있는 변수를 관리하는 것 입니다.
useRef 로 관리하는 변수는 값이 바뀐다고 해서 컴포넌트가 리렌더링되지 않습니다.
리액트 컴포넌트에서의 상태는 상태를 바꾸는 함수를 호출하고 나서 그 다음 렌더링 이후로 업데이트 된 상태를 조회 할 수 있는 반면, useRef 로 관리하고 있는 변수는 설정 후 바로 조회 할 수 있습니다.
이 변수를 사용하여 다음과 같은 값을 관리 할 수 있습니다.
- setTimeout, setInterval 을 통해서 만들어진 id
- 외부 라이브러리를 사용하여 생성된 인스턴스
- scroll 위치
const nextId = useRef(4); // useRef() 를 사용 할 때 파라미터를 넣어주면, 이 값이 .current 값의 기본값이 됩니다.
const onCreate = () => {
nextId.current += 1;
};