Javascript/React
Ref 사용하기
Hubring
2020. 6. 23. 00:35
Ref
DOM을 직접적으로 건드려야 할 경우 Ref를 사용한다.
컴포넌트 내부에서 DOM을 직접 접근해야할 경우 ref를 사용, 먼저 ref를 바로 사용하지 않고 원하는 기능을 구현할 수 있는지 반드시 고려한 후 사용.
서로다른 컴포넌트끼리 데이터를 교류할 때 ref를 사용한다면 잘못된 설계로 유지 보수가 힘들어짐.
컴포넌트 끼리 교류할 때는 언제나 데이터를 부모 <-> 자식 흐름으로 교류
효율적인 교류를 위해 리덕스 혹은 Context API를 이용할 수 있음.
DOM을 사용해야하는 상황
- 특정 input에 포커스 주기
- 스크롤 박스 조작하기
- Canvas 요소에 그림그리기 등
클래스형 컴포넌트에서 Ref 사용
import React, { Component } from 'react';
import './ValidationSample.css';
class ValidationSample extends Component {
input = React.createRef();
state = {
password: '',
clicked: false,
validated: false
};
handleChange = e => {
this.setState({
password: e.target.value
});
};
handleButtonClick = () => {
this.setState({
clicked: true,
validated: this.state.password === '0000'
});
this.input.current.focus();
};
render() {
return (
<div>
<input
ref={this.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>
);
}
}
export default ValidationSample;
함수형 컴포넌트에서 Ref 사용 ( useRef Hook이용 )
import React, { useState, useMemo, useRef, useCallback } from 'react';
const getAverage = numbers => {
console.log('평균값 계산중..');
if (numbers.length === 0) return 0;
const sum = numbers.reduce((a, b) => a + b);
return sum / numbers.length;
};
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState('');
const inputEl = useRef(null);
const onChange = useCallback(e => {
setNumber(e.target.value);
}, []); // 컴포넌트가 처음 렌더링 될 때만 함수 생성
const onInsert = useCallback(() => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber('');
inputEl.current.focus();
}, [number, list]); // number 혹은 list 가 바뀌었을 때만 함수 생성
const avg = useMemo(() => getAverage(list), [list]);
return (
<div>
<input value={number} onChange={onChange} ref={inputEl} />
<button onClick={onInsert}>등록</button>
<ul>
{list.map((value, index) => (
<li key={index}>{value}</li>
))}
</ul>
<div>
<b>평균값:</b> {avg}
</div>
</div>
);
};
export default Average;
참고.
리액트를 다루는 기술 - 김민준 지음, 길벗 출판