일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- k8s
- 쿠버네티스
- 파이썬
- react
- 블록체인
- CSS
- 가상화
- 컴퓨터공학
- AWS
- docker
- 웹
- 알고리즘
- 리액트
- 솔리디티
- 이더리움
- 자바스크립트
- es6
- TypeScript
- node.js
- BFS
- 타입스크립트
- 프론트엔드
- 백엔드
- JavaScript
- HTML
- kubernetes
- 클라우드
- next.js
- 백준
- 이슈
- Today
- Total
즐겁게, 코드
useRef 훅에 대하여 본문
useRef
훅은 마치 북극성에 비유할 수 있는 훅이다.
훅을 소개하기 앞서 코드를 하나 살펴보자.
import React, { useState } from "react";
function UseRef() {
const [name, setName] = useState("");
return (
<>
<input value={name} onChange={(e) => setName(e.target.value)}></input>
<div>이름 : {name}</div>
</>
);
}
export default UseRef;
이름을 입력받는 입력란과 이름을 출력하는 요소가 있다.
만약 상태가 업데이트될 때마다 컴포넌트가 렌더링되는 횟수를 구해야 한다면, 어떻게 구할 수 있을지 잠깐 생각해보자.
아마 useRef
를 모르는 사람이라면 이렇게 코드를 작성할 것이다. (실제로 나도 이렇게 작성했었다.)
import React, { useState, useEffect } from "react";
function UseRef() {
const [name, setName] = useState("");
const [renderCount, setRenderCount] = useState(1);
useEffect(() => {
setRenderCount((prev) => prev + 1);
});
return (
<>
<input value={name} onChange={(e) => setName(e.target.value)}></input>
<div>이름 : {name}</div>
<div>렌더링 횟수 : {renderCount}번</div>
</>
);
}
export default UseRef;
이름을 수정할 때마다 useEffect
훅에서 렌더링 횟수가 업데이트되고 얼핏 보면 성공적으로 렌더링 횟수를 구하는 것처럼 보인다.
그러나 잘 생각해보면 renderCount
역시 상태값이므로 renderCount
가 업데이트되면 렌더링 횟수가 또 올라가게 되고, 이는 결국 무한히 재귀적인 렌더링으로 이어져 에러를 출력하게 된다.
답이 없어보이는 이 문제는 useRef
를 사용하면 아주 간단하게 렌더링 횟수를 구할 수 있다.
import React, { useState, useRef, useEffect } from "react";
function UseRef() {
const [name, setName] = useState("");
const renderCount = useRef(0);
useEffect(() => {
renderCount.current += 1;
}, [name]);
return (
<>
<input value={name} onChange={(e) => setName(e.target.value)}></input>
<div>이름 : {name}</div>
<div>렌더링 횟수 : {renderCount.current}번</div>
</>
);
}
export default UseRef;
useRef
값의 변경은 컴포넌트를 재렌더링하지 않으며, 렌더링에 영향을 받지도 않는다.
즉 컴포넌트의 업데이트에 따른 부수효과(Side effect)의 영향을 받아서는 안되는 값은 useRef
를 통해 사용할 수 있다.
[useRef 훅의 사용법]
import React, { useRef } from "react"
const value = useRef(초기값);
// useRef로 사용한 값은 current 속성값을 통해 조작한다.
value.current = value.current + 1;
물론 실제 코드를 짤 때 컴포넌트의 렌더링 횟수를 구해야 하는 일은 드물다.
useRef
훅은 주로 DOM 요소를 직접 조작해야 할 때 사용되는데, document.querySelector()
등으로 DOM을 직접 선택하는 것은 리액트의 안티패턴 중 하나다.
(돔 요소를 직접 수정하게 되면 비즈니스 로직과 UI를 수정하는 코드가 뒤섞여 복잡해진다.)
import React, { useState } from "react";
function UseRef() {
const [name, setName] = useState("");
return (
<>
<input value={name} onChange={(e) => setName(e.target.value)}></input>
<div>이름 : {name}</div>
<button>포커스 이동</button>
</>
);
}
export default UseRef;
이번에는 useRef
를 활용해 버튼을 누르면 입력창에 포커스가 맞춰지도록 코드를 짜보자.
import React, { useRef, useState } from "react";
function UseRef() {
const [name, setName] = useState("");
const inputRef = useRef(null);
return (
<>
<input
ref={inputRef}
value={name}
onChange={(e) => setName(e.target.value)}
></input>
<div>이름 : {name}</div>
<button onClick={() => inputRef.current.focus()}>포커스 이동</button>
</>
);
}
export default UseRef;
이렇게 useRef
를 사용한 변수를 요소의 참조라고 생각해 ref = {inputRef}
로 사용한 모습이다.
이제 저 입력창은 inputRef.current
를 통해 어떤 부작용도 없이 조작할 수 있게 되었다.
'🎨 프론트엔드 > React.js' 카테고리의 다른 글
defaultProps에 대한 짧은 고찰 (0) | 2021.01.31 |
---|---|
useContext 훅에 대하여 (0) | 2021.01.05 |
useMemo 훅에 대하여 (0) | 2020.12.30 |
Portal 사용하기 (0) | 2020.12.28 |
useEffect 훅에 대하여 (1) | 2020.12.28 |