
이 포스팅은 김민준님의 '리액트를 다루는 기술'을 요약한 글입니다.
일반 HTML에서 DOM에 이름을 달 때는 id를 사용합니다.
리액트 프로젝트 내부에서 DOM에 이름을 다는 방법이 바로 ref(reference의 줄임말) 개념입니다.
ref는 전역적으로 작동하지 않고 컴포넌트 내부에만 작동하기 떄문에 중복 id를 가진 DOM이 여러개 일 걱정이 없습니다.
ref는 DOM을 꼭 직접 건드려야 할 때 사용합니다.
하지만 리액트에선 DOM에 접근하지 않아도 state로 구현 가능합니다.
DOM을 꼭 사용해야 하는 상황?
- 특정 input에 포커스 주기
- 스크롤 박스 조작하기
- Canvas 요소에 그림 그리기 등
ref를 만들기: 콜백 함수 사용 ← ref를 달고자 하는 요소에 ref라는 콜백 함수를 props로 전달. 이 콜백 함수는 ref 값을 파라미터로 전달 받아 컴포넌트의 멤버 변수로 설정
ex> <input ref={(ref) = > {this.input = ref }} />
this.input은 input 요소의 DOM을 가리킴
리액트에 내장되어 있는 createRef 함수 사용
jsx
import {Component} from 'react';
import './ValidationSample.css';
class ValidationSample extends Component{
state = {
password:'',
clicked: false,
validated: false
}
handleChange = (e) => {
this.setState({
password: e.target.value
});
}
handleButtonClick = (e) => {
this.setState({
clicked: true,
validated: this.state.password === '0000'
});
this.input.focus();
}
render(){
return(
<div>
<input
ref={(ref) => this.input=ref}
type='password'
value={this.state.password}
onChange={this.handleChange}
className={this.state.clicked ? (this.state.validated ? 'sucess' : 'failure') : ''}
/>
<button onClick={this.handleButtonClick}>검증하기</button>
</div>
);
}
}
export default ValidationSample;
컴포넌트 내부에 있는 DOM을 컴포넌트 외부에서 사용할 때 사용합니다.
<MyComponent // MyComponent 내부 메서드 및 멤버 변수에도 접근 가능
ref={(ref) => {this.myComponent=ref}}
/>
// ScrollBox.js
import {Component} from 'react';
class ScrollBox extends Component{
scrollToBottom = () =>{
const { scrollHeight, clientHeight } = this.box;
this.box.scrollTop = scrollHeight - clientHeight;
}
render(){
const style = {
border:'1px solid black',
height:'300px',
width:'300px',
overflow:'auto',
position:'relative'
};
const innerStyle = {
'width':'100%',
'height':'650px',
'background':'linear-gradient(white, black)'
}
return(
<div
style={style}
ref={(ref) => {this.box=ref}}
>
<div style={innerStyle} />
</div>
);
}
}
export default ScrollBox;
// App.js
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()} /* 처음 렌더링 될 때 this.scrollBox는 undefined 이므로 함수화 해서 넣어주기 */>
맨 밑으로
</button>
</div>
);
}
}
export default App;
컴포넌트 내부에서 DOM에 직접 접근식 ref 사용.
다른 컴포넌트끼리 데이터 교류시는 ref 사용 X = 컴포넌트끼리 데이터 교류시 부모 ↔ 자식 으로 교류 = 리덕스 등..