[React] useRef

ksj0314·2024년 6월 28일
0

React

목록 보기
13/27

useRef는 크게 두 가지 경우에 사용할 수 있습니다.

  1. 변수의 값을 변경하고 싶으나 컴포넌트의 렌더링은 피하고 싶은 경우
  2. DOM요소에 접근하고자 하는 경우

1. 값 참조

useRef는 초기값으로 설정된 current라는 단일 속성을 사용합니다.

// JSX
import { useRef } from 'react';

function Counter() {
	const countRef = useRef(0);

    function handleClick() {
        countRef.current = countRef.current + 1;
    	alert('You clicked ' + countRef.current + ' times!');
    }

    return (
     	<>
            <button onClick={handleClick}>
                Click me!
            </button>
            <p>count: {countRef} </p>
        </>
    );
};
  • useRef를 import하여 사용합니다.
  • countRef는 초기값이 0으로 설정되있으며 클릭하여 1씩 증가하는 함수를 만들었습니다.
  • 이 때 countRef의 current값은 1씩 증가되는 것을 alert로 확인 가능합니다.
  • 다만, 값의 변경은 가능하나 렌더링되지 않아 p태그로 감싼 영역은 항상 count: 0으로 출력됩니다.
  • 변수의 값은 유지하되 불필요한 렌더링은 막고 싶은 경우 사용할 수 있습니다.

1) ref | state | 일반변수

위 사항을 통해 ref와 state는 렌더링에서 차이가 있는 것을 알 수 있습니다.
그렇다면 일반 변수와 ref의 차이는 무엇일까요?

// JSX
function Counter() {
	const countRef = useRef(0);
	const count = 0;

    return (
     	~~~
    );
};

위와 같이 ref와 일반 count변수를 생성하고 값을 변경할 때에
Counter 컴포넌트가 렌더링된다면 countRef는 값이 유지되며 count는 다시 0으로 초기화됩니다.

state => 값 저장 + 렌더링
ref => 값 저장
일반 변수 => 값 초기화


2. DOM 조작

// JSX
import { useRef } from 'react';

function MyComponent() {
	const inputRef = useRef(null);

	return(
    	<>
        	<input ref={inputRef} />
        </>
    );
}
  • DOM요소의 ref 속성에 ref객체를 전달합니다.
  • current 속성을 사용해 여러 DOM 조작이 가능합니다.

1) 초점 맞추기

  • current.focus()를 이용해 해당 요소에 초점을 맞출 수 있습니다.

2) 스크롤

  • current.scrollTop, current.scrollLeft의 값을 변경하여 버튼식 스크롤 조작이 가능합니다.

3) video 재생/정지

  • current.play(), current.pause()를 이용해 조작 가능합니다.

4) 부모 컴포넌트에서 자식 요소에 접근

// JSX
import { forwardRef, useRef } from 'react';

const MyInput = forwardRef((props, ref) => {
    return <input ref={ref} />;
});

export default function Form() {
	const inputRef = useRef(null);

    return (
        <>
			<MyInput ref={inputRef} />
        </>
     );
}
  • forwardRef로 자식 컴포넌트를 감싸서 사용하면 부모 컴포넌트의 ref객체를 가져와 DOM요소에 할당 가능합니다.

5) 컴포넌트의 사이즈, 위치 측정

// JSX
function Component(props) {

    const [position, setPosition] = useState({ top: 0, left: 0 });
    const [size, setSize] = useState({ width: 0, height: 0 });
	const mainRef = useRef(null);

	useEffect(() => {
        const handleResize = () => {
            const mainElement = mainRef.current;
            if (mainElement) {
                const rect = mainElement.getBoundingClientRect();
                setPosition({
                    top: rect.top,
                    left: rect.left
                });
                setSize({
                    width: mainElement.offsetWidth,
                    height: mainElement.offsetHeight
                });
            }
        };     
        setTimeout(() => {
            handleResize();
        }, 10);
        window.addEventListener("resize", handleResize);
        return () => window.removeEventListener("resize", handleResize);
    }, [position, size]);

	return (
        <Main ref={mainRef}>
        </Main>
    );
 
}
  • current의 getBoundingClientRect()의 top과 left등의 값을 사용해 위치값을 가져올 수 있습니다.
    ※ 해당 값은 부모 요소로부터 값이 아니라 화면내에서의 값입니다.
  • current의 offsetWidth과 offsetHeight을 이용해 컴포넌트의 사이즈를 측정할 수 있습니다.
  • 위 코드는 버튼을 눌러 측정하는게 아닌 컴포넌트가 렌더링되고 바로 측정하기 때문에 if문을 이용해 mainRef에 초기값이 할당되었는지 (null인 경우 if문 실패) 확인하고 있습니다.

3. 배열로 사용하기

같은 이름의 Ref사용 혹은 반복문으로 컴포넌트를 사용할 때 각각에 Ref를 사용하려고 할 때 배열로 사용하고 싶을 수 있습니다.

배열에 useRef()를 여러개 사용하면 됩니다.


해당 내용은 React 공식 문서를 참고하여 작성되었습니다.

>> 공식 문서 자세히보기

0개의 댓글