DOM에 직접적으로 접근할 때 사용합니다. focus나 text selection 또는 애니메이션을 직접적으로 제어할 때 ref에 접근하려는 DOM 요소를 담아두고, ref의 current 프로퍼티를 통해 그 DOM에 접근할 수 있습니다.
클래스 컴포넌트에서 ref를 사용할 경우, ref의 current 프로퍼티 값은 클래스의 마운트된 인스턴스가 됩니다.
함수 컴포넌트는 인스턴스가 없기 때문에 ref 속성을 사용할 수 없습니다. 함수 컴포넌트에서 ref를 사용하려면, forwardRef를 사용하거나 클래스 컴포넌트로 전환해야합니다. 또한 함수 컴포넌트 내에서 useRef를 사용하여 DOM 요소나 클래스 컴포넌트에 ref 속성을 부여할 수도 있습니다.
컴포넌트에서 받은 ref를 자식 컴포넌트에 내려줄 때 사용됩니다. forwardRef의 두 번째 인자로 받은 ref를 자식 컴포넌트의 ref 속성에 넣어줍니다. 고차 컴포넌트에서 내부 컴포넌트에 ref를 사용할 때도 forwardRef를 사용합니다.
DOM 트리 계층 구조 바깥에서 자식 요소를 렌더링할 때 portal을 사용합니다. 그 예로는 modal, tooltip, hovercard 등이 있습니다.
자식 컴포넌트는 부모 컴포넌트의 폭과 넓이를 상속받으므로, 자식 컴포넌트가 잘릴 수 있습니다. portal을 사용해서 자식 컴포넌트를 부모 컴포넌트 밖에서 렌더링하면 부모 컴포넌트의 폭과 넓이에 영향을 받지 않습니다.
portal 노드에서 발생한 이벤트는 React 트리에서의 상위로 전달되기 때문에, DOM 트리에서 상위에 존재하지 않았더라도 React 트리에서 상위에 존재한다면 이벤트가 전달됩니다.
const Example = () => {
const ref = createRef(null);
const [shouldRerender, setShouldRerender] = useState(false);
useEffect(() => {
console.log(ref);
}, [ref]);
const rerender = () => {
setShouldRerender(!shouldRerender);
};
return (
<div>
<div ref={ref}> Example </div>
<button onClick={rerender}> rerender </button>
</div>
);
};
- 함수형 컴포넌트는 상태가 바뀔 때 마다 매번 새롭게 호출된다
- 그렇기 때문에 ref가 가리키는 DOM 요소가 리렌더링 되는 것과 상관없이
새로운 ref 객체
가 계속해서 생성된다- 버튼을 누르게 되면 해당 컴포넌트의 상태가 바뀌기 때문에 함수 컴포넌트가 다시 호출된다
- 하지만 div는 변경되는 부분이 없으므로 리렌더링이 일어나지 않는다
- 하지만 createRef는 계속해서 호출되기 때문에 콘솔 창에는 ref에 대한 내용이 클릭할 때 마다 출력된다
- state
- 컴포넌트 라이프 사이클 내에서 유지됨
- 변경 가능
- 값 변경시 리렌더링 발생
- ref
- 컴포넌트 라이프 사이클 내에서 유지
- 변경 가능
- 값 변경시 리렌더링 발생하지 않습니다