render 메서드에서 만들어지는 React Element나 DOM 노드에
직접 접근
하기 위한 방법이예요.
리액트 컴포넌트에서는 State를 조작해서 렌더링을 제어하죠.
👉 직접적으로 React Element를 수정하지 않아요.
⚠️ 하지만 가끔은 React Element에 직접 접근해서 수정해야할 일이 생겨요. 이 때 Ref를 사용하면 됩니다.
// class
constructor(props) {
super(props);
this.myRef = React.createRef(); // 이렇게 만들어주고
}
render() {
return <div ref={this.myRef} /> // 사용합니다!
}
// function
const AComponent = () => {
const myRef = useRef(null);
return (
<div ref={myRef}>
....
</div>
)
}
const myRef = this.myRef.current;
...
...
<Cutsom ref={this.myRef}/>
current Attribute로 사용하면 됩니다. (function도 마찬가지입니다)
👇 보통 포커스, 텍스트 선택 영역, 혹은 미디어의 재생을 관리할 때 사용합니다.
const textInputRef = useRef(null);
focusTextInput = () => {
// DOM API를 사용하여 text 타입의 input 엘리먼트를 포커스합니다.
if (textInputRef)
textInputRef.current.focus();
};
애니메이션을 직접적으로 실행시킬 때도 사용하고,
서드 파티 DOM 라이브러리를 React와 같이 사용할 때도 사용합니다.
📖 전부 DOM을 직접적으로 잡아야 실행할 수 있는 메서드들을 사용할 때네요.
⚠️주관적인 생각입니다!
React는 상태에 따라 렌더링되는 방식을 채택하고 있어요.
최대한 Element를 직접 조작하지 않아야 최적화 문제가 없을 것 같아요.
보통 상태를 상위 계층으로 올리면 (State 끌어올리기) Ref를 사용하지 않아도 대부분 해결된다고 하니 노력해봅시다.
컴포넌트가 마운트될 때
React는 current property에 DOM 엘리먼트를 대입합니다.
마운트가 해제될 때는
current property를 다시 null로 돌려놓습니다.
ref를 수정하는 작업은 componentDidMount나 componentDidUpdate 생명주기 메서드가 호출되기 전
에 이루어집니다.
우리가 ref에 접근할 수 있는 시점은 React 노드가 RealDOM에 반영되는 시점부터입니다.
즉, 믿을만 하다는거죠.
😢 그러니 DOM API인 document.querySelector
을 쓸 수는 있지만 라이프사이클에 따라 DOM 요소를 제대로 가져오지 못하는 경우가 있습니다.
😀 ref를 통해 이를 해결할 수 있을 거예요.