DOM에 직접 접근할때.
예시: <div id="user"></div>
로 id를 주어서,
기존에 document.getelementbyid()
등을 사용해서 직접 해당 DOM 요소에 접근하였다.
이렇듯 html에서는 Id를 붙였다면, React 에서는 ref를 사용한다.
React에서 State로만 해결할 수 없고, DOM을 반드시 직접 건드려야 할 때 사용한다.
컴포넌트를 렌더링 시키지 않고, dom에만 접근하여 내가 원하는 효과를 주고싶을때
실무에서는 어쩔수 없이 사용할 때를 제외하고 웬만해선 ref를 지양하는편이다.
이유는 DOM 조작 이벤트 자체가 무겁고, React 자체가 최대한 DOM을 조작안하려고 가상돔을 쓰기 때문이다.
예시) dom-to-image
라는 특정 영역을 png로 저장하는 라이브러리를 사용하기위해
원하는 요소에 ref를 부여하고 사용하는 코드
import { useRef } from 'react';
import domtoimage from 'dom-to-image'
const TestComponent = (props) => {
const {id, nickName} = props;
const personInfo = useRef(); // 1. personInfo에 useRef 객체 생성
// 영역을 png로 저장하는 함수
const onClick = function () {
domtoimage.toPng(personInfo.current) // 3. ref를 부착한 요소에 .current로 접근
.then(function (blob) {
window.saveAs(blob, 'user-card.png');
})
};
return (
<div>
<div className="box" ref={personInfo}> // 2. div.box 요소에 위에서 생성한 ref 부착.
<p> {id} - {nickName} 테스트 영역 </p>
</div>
<button onClick={onClick}>저장</button>
</div>
);
}
아래 코드는 버튼을 누르면 input text에 포커스를 주는 코드이다.
클래스형은 ref를 달고자 하는 요소에 ref라는 콜백 함수를 전달하면 된다.
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
// textInput DOM 엘리먼트를 저장하기 위한 ref를 생성
this.textInput = React.createRef();
this.focusTextInput = this.focusTextInput.bind(this);
}
focusTextInput() {
// DOM API를 사용하여 명시적으로 text 타입의 input 엘리먼트를 포커싱
// current을 사용해서 프로퍼티에 접근, focus로 포커싱
this.textInput.current.focus();
}
render() {
// React에게 우리가 text 타입의 input 엘리먼트를
// 우리가 생성자에서 생성한 `textInput` ref와 연결하고 싶다고 이야기합니다.
return (
<div>
<input
type="text"
//ref 콜백함수로 부착
ref={(ref) => (this.textInput = ref)} />
<input
type="button"
value="Focus the text input"
onClick={this.focusTextInput}
/>
</div>
);
}
}
이 방법은, 컴포넌트 내부의 DOM 요소를 컴포넌트 외부에서 사용해야 할 때 활용한다.
import React, { Component } from "react";
import "./App.css";
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;
여기서 <button onClick={this.scrollBox.ScrollToBottom()}>
로 쓰게되면,
컴포넌트가 처음 렌더링 될때 scrollBox 컴포넌트에 ref가 달리기 전이므로, undefined.ScrollToBottom()
을 실행하여 오류가 난다.
그러므로 화살표 함수를 만들면 버튼을 누를때 실행되므로, 이미 button을 누를때는 ref 가 붙어있는 상황이기 때문에 오류가 발생하지 않는다.