상세 컨텐츠

본문 제목

[리액트스타터2] 5장. ref

22-23/22-23 리액트 스타터 2

by mk020 2022. 11. 5. 10:00

본문

728x90

* ref(reference의 줄임말) : HTML에서 id를 사용하여 DOM에 이름을 다는 것처럼 리액트 프로젝트 내부에서 DOM에 이름을 다는 방법

 

5장에서는 클래스형 컴포넌트에서 ref를 사용하는 법을 공부한다. (함수형 컴포넌트에서 ref 사용 시, Hooks 사용 > 8장 )

=> 특정 DOM에 작업을 해야할 때 사용하는데, 특히 DOM을 꼭 직접적으로 건드려야 할 때 사용해야 한다

1. 예제 컴포넌트 생성

.success {
background-color : lightgreen;
}

.failure {
background-color : lightcoral;
}
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 = () => {
this.setState({
clicked:true,
validated:this.state.password==='0000'
})
}

render () {
return (
<div>
<input 
type="password"
value={this.state.password}
onChange={this.handleChange}
className={this.state.clicked ? (this.state.validated ? 'success' : 'failure' ) : '' }
/>

<button onClick = {this,handleButtonClick}>검증하기</button>
</div>
);
}
}

input에서 onChange 이벤트 발생 시, handleChange를 호출하여 state의 password 값을 업데이트한다

button에서 onClick 이벤트 발생 시, handleCuttonClick을 호출하여 clicked는 참, validated는 검증 결과로 설정한다

input의 className 값은 버튼 클릭 전에는 비어있는 문자열이고, 클릭 후에는 success 또는 failure를 가지며, 그 값에 따라 input의 색상이 변경된다

 

2. App 컴포넌트에서 예제 컴포넌트 렌더링

import {Component} from 'react';
import ValidationSample from './ValidationSample';

class App extends Component {
render () {
return {
<ValidationSample/>
);
}
}

export default App;

이와 같은 작업은 굳이 DOM에 접근하지 않아도 state로 구현 가능하다

 

state만으로 해결할 수 없는 기능은 다음과 같다

1. 특정 input에 포커스 주기

2. 스크롤 박스 조작하기

3. Canvas 요소에 그림 그리기

이와 같은 경우에는 DOM에 직접 접근해야 하기 때문에, ref를 사용해야 한다

 

가장 기본적인 방법으로, ref를 달고자 하는 요소에 ref라는 콜백 함수를 props로 전달한다

이때, 이 콜백함수는 ref값을 파라미터로 전달하며, 함수 내부에서 ref를 컴포넌트 매개변수로 설정한다

 

<input ref={(ref)=> {this.input = ref}} />

여기서 this.input이 input 요소의 DOM을 가리킨다

ref의 이름은 자유롭게 지정 가능하다

 

리액트 내장 함수인 createRef를 사용하는 방법이다

 

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;

컴포넌트 내부에서 멤버 변수로 React.createRef() 를 담고, 해당 멤버 변수를 ref 달고자 하는 요소에 ref props로 넣어준다

콜백 함수와 달리, this.input.current로 DOM에 접근한다.

주로 컴포넌트 내부에 있는 DOM을 컴포넌트 외부에서 사용할 때 쓴다.

 

이번 절에서는 스크롤 박스가 있는 컴포넌트를 만들고, 부모 컴포넌트에서 스크롤 바를 아래로 내리는 작업을  실행해본다

import {Component} from 'react';

class ScrollBox extends Component {
render () {
const style = {
border : '1px solid black',
height:'300px',
width: '300px',
overflow: 'auto',
position: 'relative'
};

const innerStyle = {
height:'650px',
width: '100%',
background : 'linear-gradient(white, black)'
}

return (
<div 
style={style}
ref={(ref)=> {this.box=ref}}>
<div style={innerStyle}/>
</div>
);
}
}

export default ScrollBox;
import {Component} from 'react';
import ScrollBox from './ScrollBox';

class App extends Component {
render () {
return (
<div>
<ScrollBox/>
</div>
);
}
}

export default App;

2. 컴포넌트에 메서드 생성

javascript로 스크롤 바를 내릴 때 DOM 노드의 값을 사용한다.

* scrollTop : 세로 스크롤바 위치

* scrollHeight : 스크롤이 있는 박스 안 div 높이

* clientHeight : 스크롤이 있는 박스의 높이

import {Component} from 'react';

class ScrollBox extends Component {

scrollToBottom = () => {
const {scrollHeight, clientHeight } = this.box;
this.box.scrollTop = scrollHeight - clientHeight;
}

render () {
 ( ... )
 }

export default App;

 App 컴포넌트에서 ScrollBox에 ref 달고 ScrollBox 컴포넌트의 ScrollToBottom 메서드를 실행한다

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;

IV. 정리

컴포넌트 내부에서 DOM에 직접 접근할 때 ref를 사용한다

서로 다른 컴포넌트끼리 데이터 교류 시, ref를 사용하는 것은 리액트 체계에서 어긋난 설계이다.

(규모가 커질수록 유지 및 보수가 어려워진다)

* 데이터는 부모 <-> 자식 흐름으로 교류해야한다

 

Quiz

Q1) (   )란 reference의 줄임말로, HTML에서 id를 사용하여 DOM에 이름을 다는 것처럼 리액트 프로젝트 내부에서 DOM에 이름을 다는 방법이다.

Q2) ref를 사용할 때는 (                                      )이다.

Q3) DOM에 접근하지 않아도 (             )를 사용해 기능을 구혈할 수 있다.

Q4) ref를 사용하는 방법은 2가지로, (                   )를 통한 ref 설정과  (                   )를 통한 ref 설정이 있다

Q5) createRef는 리액트에 내장되어 있는 함수이다 ( o, x )

Q6) 리액트에서 컴포넌트에는 ref를 달 수 없다 ( o, x )

Q7) 서로 다른 컴포넌트끼리 데이터 교류할 때는 ref를 사용해야 한다 ( o, x )

Q8) 콜백 함수를 사용해 ref를 다는 예시 코드를 작성하시오 ( ref 이름은 자유 지정)

Q9) createRef를 통해 ref를 설정해 준 DOM에 접근할 때 조회하는 코드를 작성하시오.

 

코드 작성 문제 예시 답안

 

Q8) 콜백 함수를 사용해 ref를 다는 예시 코드를 작성하시오 ( ref 이름은 자유 지정)

<input ref={(ref)=> {this.input = ref}} />

Q9) createRef를 통해 ref를 설정해 준 DOM에 접근할 때 조회하는 코드를 작성하시오.

this.input.current

ⓒ엘리

728x90

관련글 더보기