보통, 원래, 일반적인 경우:
- 부모와 자식 컴포넌트가 있을 때, 자식 컴포넌트를 수정하려면 부모 컴포넌트에서 새로운 props를 전달하여 자식을 리렌더링함
특수한 경우:
- 그런 과정 안 거치고 직접 자식을 수정하고 싶음
- 컴포넌트 인스턴스( 클래스로 선언된 컴포넌트, this 키워드로 참조되는 대상 ), DOM 엘리먼트
쓰기 전 경고:
- state에 어디에 있어야 할지 먼저 고민해야 함
생성:
- 컴포넌트의 인스턴스 생성할 때, Ref를 프로퍼티로 추가 → 인스턴스 내부에서 자유롭게 접근 가능
접근:
- render 메서드 안에서 ref가 엘리먼트에 ref attribute 통해 전달되면 해당 노드에 대한 참조가 ref.current에 담김
- ref의 값
-
HTML 엘리먼트에 쓰인 경우 - ref는 자신을 전달받은 DOM 엘리먼트를 current 프로퍼티의 값으로 받음
-
컴포넌트 마운트 할 때, current 프로퍼티에 DOM 엘리먼트 대입 - 해제될 때, current 프로퍼티는 다시 null로
-
이 작업은 componentDidMount 또는 componentDidUpdate 호출되기 "전"에 발생
-
-
커스텀 클래스 컴포넌트에 쓰인 경우 - 마운트된 컴포넌트 인스턴스를 받음
콜백 ref:
- ref attr에 createRef( )로 생성된 ref가 아니라 "함수"를 전달함
- 이 함수의 인자로 컴포넌트 인스턴스나 DOM 엘리먼트가 옴 ( 다른 곳에서 저장되고 접근 가능 )
- DOM 노드에 ref를 덧붙이거나 떼어낼 때, 특정한 코드를 실행시키고 싶다면 사용
- 이를테면 useEffect를 안 써도 되는 것
this.textInput = null;
this.setTextInputRef = element => {
this.textInput = element;
};
...
render() {
return (
<div>
<input
type="text"
ref={this.setTextInputRef}
/>
<input
type="button"
value="Focus the text input"
onClick={this.focusTextInput}
/>
</div>
);
}
- 인스턴스 마운트 → ref 콜백을 DOM 엘리먼트와 함께 호출 ( ref={this.setTextInputRef })
- 인스턴스 마운트 해제 → ref 콜백을 null과 함께 호출
- .current 프로퍼티로 전달된 인자로 초기화, 변경 가능한 값을 담고 있는 "상자"
- 변경 가능한(mutable?) ref 객체; 컴포넌트 전 생애주기 내내 유지
- 렌더링을 할 때마다 동일한 ref 객체를 제공, 따라서 내용이 변경될 때 알려주지 않음
- 자식에게 명령적으로 접근하는 경우
- 순수 자바스크립트 객체를 생성하기 때문에 가변값을 유지하는 데 편리
- 값은 유지하되 굳이 리렌더링 할 필요는 없을 때
forwardRef
- ref를 자식 컴포넌트로 전달하기
- 자식 컴포넌트를 forwardRef로 감싸주면 됨
- 부모 컴포넌트는 아무것도 모름
'ref' 객체는 변경 가능한(mutable) current 프로퍼티를 가지며, 어떤 값이든 보유할 수 있는 일반 컨테이너. class의 인스턴스 프로퍼티와 유사. (a generic container whose current property is mutable and can hold any value, similar to an instance property on a class.)
function Timer() {
const intervalRef = useRef();
useEffect(() => {
const id = setInterval(() => {
// ...
});
intervalRef.current = id;
return () => {
clearInterval(intervalRef.current);
};
});
// ...
}
// ...
function handleCancelClick() {
clearInterval(intervalRef.current);
}
id는 effect에 로컬로 존재해도 충분하기 때문에 인터벌을 세팅만 하고 싶은 거라면 ref가 불필요하다.
그러나 인터벌을 이벤트 처리로 지우고 싶을 때는 ref가 유용. handleCancelClick( )
주의: 렌더링 중에 ref 설정을 피하기. 일반적으로 이벤트 처리와 effect에서 ref를 수정하는 것이 좋다.
-
컴포넌트 인스턴스에 대한 설명: it-eldorado.tistory.com/82
-
React Components, Elements, and Instances (2015. 12. 18): reactjs.org/blog/2015/12/18/react-components-elements-and-instances.html
댓글