# useRef
const ref= useRef(value)
{current : value}
- 함수형 컴포넌트에서 useRef를 부르면 ref 오브젝트를 반환해준다.
- 우리가 정해준 초기값은 ref안에 current값에 저장된다.
- 오브젝트는 수정이 가능하기 때문에 언제든 우리가 원하는값으로 변경해줄 수 있다.
- 반환된 ref는 컴포넌트의 전 생애주기를 통해 유지가 된다. 즉 컴포넌트가 계속 렌더링 되어도 언마운트 되기 전까지는 값을 유지할 수 있다.
# useRef 는 언제 사용이 될까?
1. 저장공간
- state와 비슷하게 어떤 값을 저장하는 저장공간으로 사용된다.
- state의 변화 → 렌더링 → 컴포넌트 내부변수들 초기화 ☞ 이런경우 우리가 원치않은 렌더링 때문에 곤란해질때가 있다.
state 대신 ref에 저장한다면 어떤 장점이 있을까?
- Ref의 변화 → No 렌더링 → 변수들의 값이 유지됨 ☞ 불필요한 렌더링을 막을 수 있다.
- state의 변화 → 렌더링 → 그대로 Ref의 값은 유지됨
- 컴포넌트가 아무리 렌더링이 되어도 Ref 안에 저장되어 있는 값은 바뀌지 않고 그대로 유지가 된다.
- 변경시 렌더링을 발생시키지 말아야하는 값을 다룰때 편리
2.DOM 요소에 접근
- 자바스크립트에서 document.querySelector() 를 생각하면 된다.
# 예제1
import React, { useRef, useState } from 'react';
export default function UseRef() {
const [count, setCount] = useState(0);
const countRef = useRef(0);
console.log(countRef); // countRef.current
console.log('✨렌더링...');
const increaseCountState = () => {
setCount(count + 1);
};
const increaseCountRef = ()=> {
countRef.current = countRef.current + 1;
console.log('Ref:', countRef.current);
}
return (
<div>
<p>state:{count}</p>
<p>Ref : {countRef.current}</p>
<button onClick={increaseCountState}>State 올려</button>
<button onClick={increaseCountRef}>Ref 올려</button>
</div>
);
}
- 내부적으로는 변경되지만 렌더링 되지 않으면 저장만 되고 화면에는 나타나지 않음
- 이때 렌더링시키면 내부에 저장되어있던 ref값이 화면에 나타난다.
- 값이 아무리 바껴도 렌더링이 발생되지않기 때문에 성능에 좋다.
# 예제 2
import React, { useRef, useState } from 'react';
export default function UseRef() {
const [renderer, setRenderer] = useState(0);
const countRef = useRef(0);
let countVar = 0;
const doRendering = () => {
setRenderer(renderer+1);
};
const increaseRef = () => {
countRef.current = countRef.current + 1;
console.log('ref:', countRef.current);
};
const increaseVar = () => {
countVar = countVar + 1;
console.log('var:', countVar);
};
const printResults = () => {
console.log(`ref: ${countRef.current}, var: ${countVar}`);
}
return (
<div>
<p>Ref: {countRef.current}</p>
<p>Var: {countVar}</p>
<button onClick={doRendering}>렌더!</button>
<button onClick={increaseRef}>Ref 올려</button>
<button onClick={increaseVar}>Var 올려</button>
<button onClick={printResults}>Ref Var 값 출력</button>
</div>
);
}
- 변수를 쓰지 않고 굳이 ref를 사용하는 이유는? 변수와 ref는 동시에 렌더링 시키면 값을 기억하고 있는 ref는 렌더이전의 값을 그대로 화면에 나타내주고 변수는 초기화 되어 처음값 그대로 화면에 표시된다.
# 예제 3
- ref가 유용한 상황
import React, { useEffect, useRef, useState } from 'react';
export default function UseRef() {
const [count, setCount] = useState(1);
const renderCount = useRef(1);
//const [renderCount, setRenderCount] = useState(1);
// 무한루프👎
// useEffect(() => {
// console.log('렌더링!');
// setRenderCount(renderCount+1);
// });
useEffect(() => {
renderCount.current = renderCount.current + 1;
console.log('렌더링 수 :', renderCount.current);
})
return (
<div>
<p>count: {count}</p>
<button onClick={() => {setCount(count+1)}}>올려</button>
</div>
);
}
- 무작정 useEffect를 안에 실행시면 무한루프에 빠질 수 있음
- 리렌더링 되지않는 ref를 사용해 무한루프에 빠지지 않게 만든다.
결론적으로
변화는 감지하지만 그 변화가 렌더링을 발생시키면 안되는 값을 다룰때 편리하다.
# 예제4
- DOM 요소에 접근할때
import React, { useEffect, useRef, useState } from 'react';
export default function UseRef() {
const inputRef = useRef();
useEffect(() => {
//console.log(inputRef);
inputRef.current.focus();
}, []);
const login = () => {
alert( `환영합니다. ${inputRef.current.value}!`);
inputRef.current.focus();
}
return (
<div>
<input ref={inputRef} type="text" placeholder='username' />
<button onClick={login}>로그인</button>
</div>
);
}
📌 참고
별코딩 | 리액트 훅스 시리즈
'Front-end > React' 카테고리의 다른 글
[React] React Hooks : useMemo (0) | 2023.02.24 |
---|---|
[React] React Hooks : useContext (0) | 2023.02.22 |
[React] React Hooks : useEffect (0) | 2023.02.20 |
[React] React Hooks : useState (0) | 2023.02.16 |
[React] 리액트 시작하기 (0) | 2023.02.07 |