REACT Ref
REACT Ref
ref는 참조(reference)를 뜻한다. 리액트에서는 그냥 ref라고 부른다.
지금부터 ref가 하는 일을 알아보자.
가장 기본적인 기능은 다른 DOM 요소에 접근해서 그것들로 작업할 수 있게 해주는 것이다.
간단하게 말하면 ref를 사용하면 상태 변화가 필요 없는 부분에 대해서 값을 읽어 오고만 싶을때 확인하는 용도로 사용될 수 있다.
Ref의 바람직한 사용 사례
- 포커스, 텍스트 선택영역, 혹은 미디어의 재생을 관리할 때.
- 애니메이션을 직접적으로 실행시킬 때.
- 서드 파티 DOM 라이브러리를 React와 같이 사용할 때.
선언적으로 해결될 수 있는 문제에서는 ref 사용을 지양해야한다.
아래 AddUser라는 컴포넌트가 있다고 가정하에 사용 방법을 익혀보자.
1.useRef를 import한다.
import React, { useState, Fragment, useRef } from 'react';
2.컴포넌트 함수 내에서 Ref 생성하고 ref 어트리뷰트를 통해 React 엘리먼트에 부착하기.
const nameInputRef = useRef();
const ageInputRef = useRef();
//해당 useRef()에서 생성되는 값은 항상 객체다. 항상 current 프롭을 가지고 있음. current 프롭은 그 ref가 연결된 실제 값을 가지고 있음. 실제 DOM 노드인 {current: input#username}을 가지고 있음.
<input
id="username"
type="text"
ref={nameInputRef}
/>
<input
id="age"
type="number"
ref={ageInputRef}
/>
useRef();를 사용하여 nameInputRef와 ageInputRef를 생성하고 ref 어트리뷰트를 통해 React 엘리먼트에 부착한다.
3.Ref에 접근하는 방법.
const enteredName = nameInputRef.current.value
const enteredUserAge = ageInputRef.current.value
렌더링되는 메서드 안에서 ref가 엘리먼트에게 전달되었을 때, 그 노드를 향한 참조는 ref의 current 어트리뷰트에 담기게된다. 위 상황은 ref 어트리뷰트가 HTML 엘리먼트에 쓰였기 때문에 ref는 자신을 전달받은 DOM 엘리먼트를 current 프로퍼티의 값으로 받는다.
4.Ref에 접근 후 Ref로 읽은 값 활용하기
*최종 코드
import React, { useState, Fragment, useRef } from 'react';
import Card from '../UI/Card';
import Button from '../UI/Button';
import ErrorModal from '../UI/ErrorModal';
import classes from './AddUser.module.css';
const AddUser = (props) => {
const nameInputRef = useRef();
const ageInputRef = useRef();
const [error, setError] = useState();
const addUserHandler = (event) => {
event.preventDefault();
const enteredName = nameInputRef.current.value
const enteredUserAge = ageInputRef.current.value
if (enteredName.trim().length === 0 || enteredUserAge.trim().length === 0) {
setError({
title: 'Invalid input',
message: 'Please enter a valid name and age (non-empty values).',
});
return;
}
if (+enteredUserAge < 1) {
setError({
title: 'Invalid age',
message: 'Please enter a valid age (> 0).',
});
return;
}
props.onAddUser(enteredName, enteredUserAge);
nameInputRef.current.value = "";
ageInputRef.current.value = "";
nameInputRef.current.focus();
};
const errorHandler = () => {
setError(null);
};
return (
<Fragment>
{error && (
<ErrorModal
title={error.title}
message={error.message}
onConfirm={errorHandler}
/>
)}
<Card className={classes.input}>
<form onSubmit={addUserHandler}>
<label htmlFor="username">Username</label>
<input
id="username"
type="text"
ref={nameInputRef}
/>
<label htmlFor="age">Age (Years)</label>
<input
id="age"
type="number"
ref={ageInputRef}
/>
<Button type="submit">Add User</Button>
</form>
</Card>
</Fragment>
);
};
export default AddUser;
addUserHandler 함수에서 사용자에게 input에 입력받은 값을 enteredName, enteredUserAge에 각각 담아 함수 내부에서 활용함.
댓글남기기