What is ref?
ref는 reference(참조)를 뜻한다. useRef는 리액트가 제공하는 tool 중 하나로 많은 일을 처리할 수 있는 도구이지만, 이것의 가장 기본적인 역할은 어떤 DOM 요소를 참조하고, 이를 이용해서 어떤 일을 수행하는 것이다.
How to use ref?
ref는 모든 내장 html 요소에서 사용될 수 있지만, input 요소를 참조하는 것이 가장 흔한 경우 중 하나이다.
예를 들어 사용자가 어떤 값을 입력하고 그 값을 리스트 형식으로 렌더링 한다고 해 보자. 이 때 input의 값이 변할 때 마다 실행되는 onChange에서 state를 업데이트한다면 어떨까? 최종적으로 필요한 것은 사용자가 제출 버튼을 클릭했을 때의 input 값이므로, 사용자가 키를 누를 때마다 state를 업데이트 하는 것은 과하다(unnecessary work). 이럴 때 state 대신 사용할 수 있는 것이 ref이다.
+) 사용자가 리스트를 추가할 때 마다 re-rendering이 일어나야 하는데, 상위 컴포넌트에서 리스트를 state로 관리하고 있다면 input 컴포넌트에서도 state를 사용할 필요는 없다.
import {useRef} from 'react';
const AddUser = (props) => {
const userName = useRef(); // 초기값은 설정되어있지 않지만, 컴포넌트가 실행되면 값이 설정된다.
const addUserHandler = (e) => {
e.preventDefault();
props.setUserList(userName.current.value);
userName.current.value = '';
}
return (
<form onSubmit={addUserHandler}>
<label htmlFor="username">Username</label>
<input
id="username"
type="text"
ref={userName}
/>
<button type="submit">Add User</button>
</form>
);
};
- 다른 react hooks 처럼 함수형 컴포넌트 내부에서 사용할 수 있다(컴포넌트 밖 X, nested braces X).
- 컴포넌트 함수가 실행되면, useRef의 실행 결과(userName)를 연결되어있는 실제 html element로 설정한다.
- 참조하고 싶은 element에 ref라는 속성을 사용하고, 그 값으로 useRef 함수의 실행 결과를 전달한다.
- useRef 함수는 object를 반환한다.
- 이 객체에는 current라는 프로퍼티가 있고, 참조하고 있는 DOM 요소 자체를 값으로 가지고 있다. => DOM 요소를 직접 조작하기 위해 사용하는 것이 아니라, 값을 읽기 위해 사용한다.
- ex) | userName.current.value와 같이 유용한 값에 접근할 수 있다.
- state로 관리할 때 value를 양방향 바인딩하는 것이 가능했지만, ref를 이용하면 불가능 하다.
un-controlled component
useRef가 참조하고 있는 DOM 요소를 uncotrolled component라고 하는데, 말 그대로 리액트가 해당 요소를 제어하지 않기 때문이다. 리액트가 하는 역할은, 단지 그 요소를 참조할 수 있게 해주는 것 뿐이다.
+) state를 이용해서 관리하는 component는 controlled component라고 부른다.
+) React.forwardRef & useImperativeHandle
명령형 패턴으로 컴포넌트를 사용할 수 있다. 일반적인 리액트의 패턴과는 거리가 멀기 때문에 자주 사용하는 것은 좋지 않지만, 유용하게 사용할 수 있는 경우가 있다. => custom component를 ref로 참조할 수 있게 만들어 준다.
// UI/Input
const Input = React.forwardRef((props,ref) => { // 두번째 인자로 ref를 전달받는다
return (
<div>
<label htmlFor={props.id}>{props.label}</label>
<input ref={ref} type={props.type} id={props.id} {...props.input}/>
</div>
);
})
import Input from '...';
const Form = (props) => {
const inputRef = useRef();
const submitHandler = (e) => {
e.preventDefault();
console.log(inputRef.current.value);
}
return (
<form onSubmit={submitHandler}>
<Input ref={inputRef} type="text"... />
</form>
);
}
- inputRef.current.focus() | 참조하고 있는 input element에 focus를 주는 브라우저 내장 함수
'Study > React' 카테고리의 다른 글
useReducer (0) | 2022.06.19 |
---|---|
useEffect (0) | 2022.06.19 |
Fragment & Portal (0) | 2022.06.18 |
Component Styling (0) | 2022.06.18 |
Conditional contents (0) | 2022.06.17 |