ReactJS - Refs와 DOM

안녕하세요, 미래의 React 개발자 여러분! 오늘은 React 애플리케이션에서 DOM 요소와 직접 상호작용할 수 있도록 도와줄 흥미로운 주제에 대해 다룰 것입니다. 신경 쓰지 마시고, Refs와 DOM의 세상을 탐험해 보겠습니다!

ReactJS - Refs and the DOM

Refs는 무엇인가요?

자세한 내용으로 들어가기 전에 Refs가 무엇인지 이해해 보겠습니다. React에서 "Ref"는 "reference"의 약자입니다. 특정 요소에 이름표를 달아 나중에 쉽게 찾을 수 있게 하는 것과 비슷합니다. 대형 파티에서 벗어나고 싶은 최고의 친구를 따라가는 것을 상상해 보세요. 그들에게 특별한 모자나 독특한 이름표를 주는 것처럼, React에서 Ref는 특정 요소를 추적하는 데 도움을 줍니다.

Refs가 필요한 이유는 무엇인가요?

"왜 일반 JavaScript를 사용하여 요소를 선택할 수 없나요?"라는 의문이 드실 수도 있습니다. React에서는 React가 UI를 업데이트하는 효율적인 방법을 사용하기 때문에 DOM을 직접 조작하는 것을 피하려고 합니다. 그러나 Refs가 유용하게 쓰일 때도 있습니다. 이는 React의 선언적 패러다임을 벗어나 DOM 요소를 직접 작업해야 할 때입니다!

createRef()를 사용하여 Refs 생성하기

React에서 Ref를 생성하는 방법을 보겠습니다. createRef() 메서드를 사용합니다.

createRef 메서드의 서명

createRef()의 서명은 매우 간단합니다:

React.createRef()

이게 전부입니다! 매개변수가 없고, 복잡성이 없습니다. 이 메서드는 current라는 단일 속성을 가진 평凡한 객체를 반환합니다. 초기에는 이 current 속성이 null로 설정됩니다.

예제를 보겠습니다:

class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}

render() {
return <div ref={this.myRef} />;
}
}

이 예제에서 우리는 생성자에서 Ref를 생성하고 this.myRef에 할당합니다. 그런 다음 render 메서드에서 이 Ref를 div 요소에 ref 속성을 사용하여 연결합니다.

Ref를 적용하기

이제 Ref를 생성했으므로 어떻게 사용할 수 있는지 보겠습니다. Ref를 적용하는 몇 가지 방법이 있습니다.

1. DOM 요소에 Ref 적용하기

가장 일반적인 사용 사례는 Ref를 DOM 요소에 적용하는 것입니다:

class AutoFocusInput extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}

componentDidMount() {
this.inputRef.current.focus();
}

render() {
return <input ref={this.inputRef} />;
}
}

이 예제에서 우리는 입력 요소에 Ref를 생성하고 컴포넌트가 마운트된 후 자동으로 포커스를 맞춥니다. Ref의 current 속성을 통해 실제 DOM 노드에 접근할 수 있습니다.

2. 클래스 컴포넌트에 Ref 적용하기

클래스 컴포넌트에도 Ref를 사용할 수 있습니다:

class AutoScrollingList extends React.Component {
constructor(props) {
super(props);
this.listRef = React.createRef();
}

componentDidUpdate() {
const node = this.listRef.current;
node.scrollToItem(0);
}

render() {
return <MyListComponent ref={this.listRef} />;
}
}

이 경우 this.listRef.currentMyListComponent 클래스의 인스턴스를 가리킬 것입니다.

3. 함수형 컴포넌트에 Ref 적용하기

함수형 컴포넌트에는 직접 Ref를 주선할 수 없지만, forwardRef 함수를 사용하여 Ref를 전달할 수 있습니다:

const FancyButton = React.forwardRef((props, ref) => (
<button ref={ref} className="FancyButton">
{props.children}
</button>
));

class MyComponent extends React.Component {
constructor(props) {
super(props);
this.buttonRef = React.createRef();
}

render() {
return <FancyButton ref={this.buttonRef}>Click me!</FancyButton>;
}
}

이 예제에서 FancyButtonforwardRef를 사용하여 Ref를 실제 버튼 요소로 전달합니다.

createRef 사용 사례

이제 Ref를 생성하고 적용하는 방법을 알고 있으므로, 몇 가지 일반적인 사용 사례를 보겠습니다.

1. 포커스 관리, 텍스트 선택, 미디어 재생

class TextInput extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}

focusTextInput = () => {
this.inputRef.current.focus();
}

render() {
return (
<div>
<input type="text" ref={this.inputRef} />
<button onClick={this.focusTextInput}>Focus the input</button>
</div>
);
}
}

이 컴포넌트는 버튼을 클릭할 때 입력에 자동으로 포커스를 맞추도록 합니다.

2. 강제 애니메이션 트리거

class Animator extends React.Component {
constructor(props) {
super(props);
this.elementRef = React.createRef();
}

animate = () => {
this.elementRef.current.classList.add('animated');
}

render() {
return (
<div>
<div ref={this.elementRef}>Animate me!</div>
<button onClick={this.animate}>Start Animation</button>
</div>
);
}
}

여기서 우리는 Ref를 사용하여 CSS 클래스를 추가하여 애니메이션을 트리거합니다.

3. 제삼자 DOM 라이브러리와의 통합

class MapComponent extends React.Component {
constructor(props) {
super(props);
this.mapRef = React.createRef();
}

componentDidMount() {
const mapLibrary = new FancyMapLibrary();
mapLibrary.createMap(this.mapRef.current);
}

render() {
return <div ref={this.mapRef} style={{width: '100%', height: '400px'}} />;
}
}

이 예제에서 우리는 Ref를 사용하여 제삼자 맵 라이브러리가 DOM 노드에 맵을 렌더링할 수 있게 합니다.

결론

Refs는 필요할 때 React의 선언적 패러다임을 벗어나 DOM 노드나 React 요소에 직접 접근할 수 있게 해주는 강력한 도구입니다. 그러나 Refs는 신중하게 사용해야 합니다. 대부분의 경우, React의 선언적 API를 통해 원하는 결과를 얻을 수 있습니다. 하지만 추가적인 제어가 필요한 경우, Refs가 도와줄 것입니다!

기억하시오, 큰 힘에는 큰 책임이 따릅니다. Refs를 지혜롭게 사용하면 React 애플리케이션이 당신을 감사하게 여길 것입니다!

이제 우리가 논의한 메서드에 대한 빠른 참고 표를 제공합니다:

메서드 설명 예제
React.createRef() Ref 객체 생성 this.myRef = React.createRef();
ref 속성 Ref를 React 요소에 연결 <div ref={this.myRef} />
forwardRef 함수형 컴포넌트에 Ref를 전달 const FancyButton = React.forwardRef((props, ref) => ...)

coding을 즐기시고, Refs가 항상 현재 상태를 유지하시길 바랍니다!

Credits: Image by storyset