useRef를 통해서 자식 컴포넌트를 통제하고자 한다고 해보자.
리액트에서 버튼을 별도의 컴포넌트로 만들어 관리하는 일은 빈번하다.
예를 들면, 다음과 같다.
import { useEffect, useRef } from "react";
function CustomButton({ ref }) {
return (
<div onClick={() => window.alert("Good!")} ref={ref}>
<h2>This is Custom Button</h2>
</div>
);
}
function App() {
const testRef = useRef<HTMLDivElement>(null);
useEffect(() => {
console.log(testRef.current);
}, []);
return (
<div>
<p>Test Forward Ref</p>
<CustomButton ref={testRef} />
</div>
);
}
export default App;
그런데, 위의 코드에서는 Ref를 커스텀 컴포넌트의 하위 요소에 연결하고자 하였다.
상위 컴포넌트에서 생성한 ref 객체를 하위 컴포넌트에 전달하면, 그대로 사용할 수 있는 것일까?
useEffect를 사용하여 testRef 값의 변화를 감지해보지만, 변함없이 null임을 알 수 있다.
생각처럼 props를 통해서 ref 객체를 넘겨줄 수 없는 것이다.
Warning: CustomButton: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)
덤으로 위와 같은 에러 메세지를 받을 수 있다.
ref는 prop으로 전달될 수 없는 것이다.
이처럼 하위 컴포넌트로 ref를 전달하기 위해서는 평범한 방법을 사용하면 안된다.
React에서는 이러한 문제를 해결하기 위해서 forwardRef를 제공한다.
forwardRef로 반환된 컴포넌트는 props이외에 두 번째 인자로 ref를 가질 수 있다.
실제 사용법은 다음과 같다.
import { forwardRef, useEffect, useRef } from "react";
const CustomButton = forwardRef<HTMLDivElement>((props, ref) => {
return (
<div onClick={() => window.alert("Good!")} ref={ref}>
<h2>This is Custom Button</h2>
</div>
);
});
function App() {
const testRef = useRef<HTMLDivElement>(null);
useEffect(() => {
console.log(testRef.current);
}, []);
return (
<div>
<p>Test Forward Ref</p>
<CustomButton ref={testRef} />
</div>
);
}
export default App;
처음과 똑같이 커스텀 컴포넌트에 ref로 testRef를 전달했지만, forwardRef로 반환된 컴포넌트는 이전과는 다르게 두 번째 인자로 ref를 무사히 전달 받을 수 있는 것이다.
<div>
<h2>This is Custom Button</h2>
</div>
콘솔창에 찍히는 로그값으로 위와 같이 컴포넌트가 testRef 객체에 잘 연결되었음을 확인할 수 있다.
https://ko.reactjs.org/docs/forwarding-refs.html
Ref 전달하기 – React
A JavaScript library for building user interfaces
ko.reactjs.org
https://reactjs.org/warnings/special-props.html
Special Props Warning – React
A JavaScript library for building user interfaces
reactjs.org
'React' 카테고리의 다른 글
react-router-dom의 HashRouter 사용 (0) | 2023.04.08 |
---|---|
react-router-dom v6 사용하기 (0) | 2023.04.06 |
React에서 lottie 사용하기 (0) | 2023.03.19 |
리액트 createPortal 사용하기 (0) | 2023.03.18 |
reduxjs/toolkit 더 자세히 알아보기 (typescript 적용) (0) | 2023.02.27 |