const ref = useRef<number>(null);
// current 변경할 때
ref.current = 1;
위와 같은 경우, "읽기 전용 속성이므로 'current'에 할당할 수 없습니다."라는 에러 메세지가 발생합니다.
여기서 말하는 읽기 전용 속성은 어떻게 결정되는 걸까요?
useRef는 초기값(initialValue)에 따라 반환값의 타입이 크게 3가지로 나뉩니다.
여기서 RefObject
, MutableRefObject
타입을 알아야 이 3가지 타입을 구분할 수 있는데요.
이 타입은 current 속성을 readonly로 정의하여, current 값을 변경하지 못하도록 합니다.
즉 useRef가 RefObject 타입의 값을 반환한다면, current 값을 바꾸지 못합니다.
반면 MutableRefObject의 current에는 readonly가 없네요!
이 말은 즉슨 MutableRefObject 타입의 반환값은 current를 조작할 수 있습니다.
useRef(initialValue: T): MutableRefObject<T>
초기값을 null과 undefined가 아닌 값으로 설정할 경우, useRef는 MutableRefObject<T>
를 반환합니다.
MutableRefObject를 반환하니, current 값을 바꿀 수 있습니다.
ref.current = 2
그리고 current의 타입은 T 입니다.
useRef(initialValue: T | null): RefObject<T>
초기값을 null로 설정할 경우, RefObject<T>
를 반환합니다.
RefObject를 반환하여 current가 readonly 타입이기 때문에, current를 바꿀 수 없습니다.
이 경우, DOM을 참조할 때 많이 사용됩니다.
const ref = useRef<HTMLElement>(null)
// 에러 발생 x
ref.current.style.color = "blue";
한 번쯤 ref로 dom의 style를 바꾼 경험이 있으실 겁니다. 이것도 어찌보면 값을 변경한건데, 왜 에러가 발생하지 않을까요?
readonly의 대상은 current 속성입니다. current 속성의 하위 속성은 readonly의 대상이 아니기 때문에, style.color가 변경되어도 에러가 발생하지 않습니다.
useRef<T=undefined>(initialValue?: undefined): MutableRefObject<T | undefined>
초기값을 따로 지정하지 않을 경우, MutableRefObject<T | undefined>
를 반환합니다.
MutableRefObject를 반환하니, current 값을 바꿀 수 있습니다.
ref.current = 1
1번 타입(useRef(initialValue: T): MutableRefObject<T>
)과 다른 점은 current 타입에 undefined가 추가됐습니다.