학습목표 : 타입스크립트에서 useRef 오류없이 잘 사용하기
저장공간 또는 DOM요소에 접근하기 위해 사용되는 react hook이다.
인자로 넘어온 초기값을 useRef 객체의 .current 프로퍼티에 저장한다. DOM객체를 직접 가리켜서 내부 값을 변경하거나 focus() 메소드를 사용할 때 주로 사용하고, 값이 변경되어도 컴포넌트가 리렌더링되지 않도록 하기 위한 값을 저장할때도 사용한다.
//code ..
const [stateCount, setStateCount] = useState(0);
let varCount = 0;
function upState() {
setStateCount(stateCount+ 1); // upState함수 실행시 리렌더링
}
const refCount = useRef(0);
function upRef(){
++refCount.current;
console.log(refCount.current);
}
function App() {
const inputRef = useRef();
function focus() {
inputRef.current.focus();
console.log(inputRef.current);
}
return (
<div>
<input ref={inputRef} type="text" placeholder="아이디 또는 이메일" />
<button>Login</button>
<br />
<button onClick={focus}>focus</button>
</div>
);
}
input태그가 포커스되어 inputRef.current에 <input type = 'text' placeholder = '아이디 또는 이메일' 이 들어간다. 방금전까지의 예시는 자바스크립트의 예시문인데, 타입스크립트에서 useRef를 사용할 때 3가지 종류가 있다.
MutableRefObject로컬 변수 용도로 사용하는 경우 제네릭 타입과 같은 타입의 초깃값을 넣자
interface MutableRefObject<T>{
current : T;
}
T제네릭으로 넘겨준 타입의 current 프로퍼티를 가진 객체다. import { useRef } from 'react';
const App = () => {
const localRef = useRef<number>(0);
const handleBtnClick = () => {
if(localRef.current) {
localRef.current += 1;
}
};
return (
<div className = 'App'>
<button onClick = {handleBtnClick}>+1</button>
</div>
)
};
useRef를 로컬 변수로 사용하는 경우.current를 직접 수정할 수 있는 이유?useRef에 제네릭 타입과 동일한 타입의 초기 인자를 주었기 때문에. RefObjectcurrent프로퍼티를 직접 수정할 수 없음 DOM을 직접 조작하기 위해 사용할 경우,
RefObject를 사용해야하므로 초기값으로null을 넣어주자
// 1번의 예시 +
//code
const localRef = useRef<number>(null);
const handleBtnClick = () => {
localRef.current += 1; // Cannot assign to 'current' because it is a read-only property. ts(2540)
};
//code
.current가 readonly인 RefObject를 반환 // 예시 2
import { useRef } from 'react';
const App = () => {
const inputRef = useRef<HTMLInputElement>(null);
const handleBtnClick = () => {
if(inputRef.current) {
inputRef.current.value = '';
}
};
return (
<div className = 'App'>
<button onClick = {handleBtnClick}>+1</button>
<input ref = {inputRef} />
<button onClick = {handleBtnClick}>clear</button>
</div>
);
수정 불가능한 RefObject< T>를 반환하는데, inputRef.current.value가 수정 가능한 이유?
-> 정의 상current프로퍼티만 읽기 전용이므로 하위 프로퍼티인value는 수정이 가능하다.
->readonly가 shallow(얕기)이기 때문
MutableRefObject<T | undefined> //code ..
const inputRef = useRef<HTMLInputElement>();
// code ..
RefObject형만 받는데, inputRef는 정의 상 MutableRefObject가 되고, 이를 ref 프로퍼티에 넣으려해서 발생하는 에러