ref (reference) 란?
- HTML 에서 id를 사용하여 DOM에 이름을 다는 것 처럼 리액트 프로젝트 내부에서 DOM에 이름을 다는 방법
- 리액트 컴포넌트 안에서도 id를 사용할 수 있긴 하지만, id를 달아놓은 컴포넌트를 여러 번 사용할 경우 중복 id를 가진 DOM이 여러 개가 생기게 되므로 잘못된 사용이다!
- 반면에, ref는 전역적으로 작동하지 않고 컴포넌트 내부에서만 작동하기 때문에 위의 id와 같은 문제가 발생하지 않는다.
1. ref는 어떤 상황에서 사용해야 할까? → DOM을 꼭! 직접적으로 건드려야 할 때
- state를 사용하여 많은 기능을 구현할 수 있지만, state만으로 해결할 수 없는 기능들을 구현할 때
=== DOM에 직접적으로 접근해야 할 때, ref를 사용한다.- 특정 input에 포커스 주기
- 스크롤 박스 조작하기
- Canvas 요소에 그림 그리기 등
2. ref 사용
- 콜백 함수를 통한 ref 설정
- ref를 만드는 가장 기본적인 방법
- ref를 달고자 하는 요소에 ref라는 콜백 함수를 props로 전달
// this.input은 input 요소의 DOM을 가르킨다
<input ref={(ref) => {this.input=ref}} />
- createRef를 통한 ref 설정
- 리액트에 내장되어 있는 createRef라는 함수를 사용하여 ref를 만들면 더 적은 코드로 쉽게 사용할 수 있다.
(v16.3부터 사용가능) - 이 함수를 사용하여 ref를 만들기 위해서는 먼저 컴포넌트 내부에서 멤버 변수에 React.createRef()를 할당해 주어야 한다.
그리고 해당 변수를 ref를 달고자 하는 요소에 ref props로 넣어주면 ref 설정 완료!
- 리액트에 내장되어 있는 createRef라는 함수를 사용하여 ref를 만들면 더 적은 코드로 쉽게 사용할 수 있다.
import { Component } from 'react';
class RefSample extends Component {
input = React.createRef();
handleFocus = () => {
this.input.current.focus();
}
render() {
return (
<div>
<input ref={this.input} />
</div>
);
}
}
export default RefSample;
3. 컴포넌트에 ref 달기
- 주로 컴포넌트 내부에 있는 DOM을 컴포넌트 외부에서 사용할 때, 컴포넌트에 ref를 달아서 사용한다.
- 컴포넌트에 ref를 다는 방법은 DOM에 ref를 다는 방법과 동일하다.
import { Component } from 'react';
class ScrollBox extends Component {
scrollToBottom = () => {
const { scrollHeight, clientHeight } = this.box;
/*
const scrollHeight = this.box.scrollHeight;
const clientHeight = this.box.clientHeight;
*/
this.box.scrollTop = scrollHeight - clientHeight;
}
render() { (...) }
}
export default SccrollBox;
import { Component } from 'react';
import ScrollBox from './ScrollBox';
class App extends Component {
render() {
return (
<div>
<ScrollBox ref={(ref) => this.scrollBox=ref} />
<button onClick={() => this.scrollBox.scrollToBottom()}>
맨 밑으로
</button>
</div>
)
}
}
export default App;
** 주의 사항 **
→ 문법상으로는 onClick = { this.scrollBox.scrollToBottom } 형식으로 작성해도 틀린 것은 아니지만,
컴포넌트가 처음 렌더링 될 때 this.scrollBox 값이 undefined 이므로 해당 값을 읽어 오는 과정에서 오류가 발생한다!
→ 화살표 함수 문법을 사용하여 아예 새로운 함수를 만들고 그 내부에서 this.scrollBox.scrollToBottom 메서드를 실행하면, 이미 한 번 렌더링을 해서 this.scrollBox가 설정이 되어있기 때문에 버튼을 누를 때 해당 메서드의 값을 정상적으로 읽어와서 실행한다.
4. 정리
- 컴포넌트 내부에서 DOM에 직.접. 접근해야 할 때 ref를 사용한다.
- BUT, 먼저 ref를 사용하지 않고도 원하는 기능을 구현할 수 있는지 반드시 고려한 후에 활용해야 한다.
- 컴포넌트끼리 데이터를 교류할 때는 언제나 부모 ↔ 자식 흐름으로 교류해야 한다!
너무 많은 컴포넌트들 간의 교류는 리액트 사상에 어긋난 설계!! DON'T DO IT!
참고자료
- 리액트를 다루는 기술 [김민준 저]
'개발 > React' 카테고리의 다른 글
[리액트를 다루는 기술] Context API (0) | 2023.03.26 |
---|---|
[리액트를 다루는 기술] 컴포넌트 성능 최적화 (0) | 2023.03.12 |
[리액트를 다루는 기술] Hooks_useState, useEffect (0) | 2023.03.12 |
[리액트를 다루는 기술] LifeCycle Method (0) | 2023.02.26 |
[리액트를 다루는 기술] JSX (0) | 2023.02.12 |