React 레퍼런스는 useRef
를 다음과 같이 정의 하고 있습니다.
const ref = useRef(initialValue)
useRef
는 .current
프로퍼티로 전달된 인자(initialValue
)로 초기화된 변경 가능한 ref 객체를 반환합니다. 반환된 객체는 컴포넌트의 전 생애주기를 통해 유지될 것입니다.
그럼 다음과 같은 useRef
를 어떻게 활용할 수 있는지 알아보겠습니다.
const Input = () => {
const inputRef = useRef<HTMLInputElement>(null)
useEffect(() => {
inputRef.current?.focus()
}, [])
return <input ref={inputRef} type='text' value=''/>
}
inputRef
를 만들고 input
태그에 ref
porps
를 inputRef
로 설정해주면 inputRef.current
를 input
Dom으로 지정할 수 있습니다.
Dom을 선택하는데 사용되는 useRef
는 아주 다양하게 사용할 수 있으니 알고 있으면 유용할 것이라고 생각합니다.
const Timer = (startTime) => {
const [time, setTime] = useState(startTime)
// ref로 하기
const interval = useRef<NodeJS.Timeout | null>(null)
const stop = () => {
clearInterval(interval.current as NodeJS.Timeout)
}
const start = () => {
interval.current = setInterval(() => {
setTime((prev) => prev - 1)
}, 1000)
}
// 일반 변수로 하기
let interval : NodeJS.Timeout
const stop = () => {
clearInterval(interval)
}
const start = () => {
interval = setInterval(() => {
setTime((prev) => prev - 1)
}, 1000)
}
useEffect(() => {
return () => {
clearInterval(interval)
}
}, [])
return (
<div className={styles.container}>
Timer : {time}{' '}
<button type='button' onClick={stop}>
정지
</button>
<button type='button' onClick={start}>
시작
</button>
</div>
)
}
다음과 같이 Timer를 설정하고 setInterval
과 clearInterval
을 이용해서 시작과 정지를 하게끔 하려고 하면 공용으로 사용할 수 있는 setInterval
이 할당된 변수가 필요합니다. 하지만 이 변수를 설정하면 1초마다 계속 해서 새로운 변수가 생성되게 됩니다. 그렇게 되면 별로 좋지 않을 것입니다(?). 그래서 useRef
를 가지고 useRef
의 current
에 저장하여서 계속 해서 새로운 변수가 생성되는 것을 막을 수 있습니다. 이는 setTimeout
도 똑같이 적용하여 사용할 수 있습니다.