티스토리 뷰
useRef는 컴포넌트 내부에서 직접 DOM을 조작해야 할 때 사용합니다.
React에서도 바닐라 자바스크립트와 마찬가지로 JSX 엘리먼트에 id속성을 부여하고, 자바스크립트로 document.getElementById(id)를 통해서 DOM요소를 조작할 수 있습니다.
그러나 React는 컴포넌트로 이루어져 있고, 컴포넌트는 재사용됩니다. 컴포넌트의 JSX엘리먼트에 id를 부여하면, id는 유일해야 하는데 중복 id를 가진 DOM이 여러개 생기니 잘못된 사용입니다.
또한 React에서는 state를 사용하여 웹페이지를 쉽게 조작할 수 있습니다.
input의 DOM요소를 가져오고, onChange이벤트로 innerText를 변화시키며 직접 DOM을 조작하지 않아도,
[value, setValue] = useState(''), input에 value속성을 {value}로 주고, onChange이벤트로 setValue(event.target.value)를 주는 정도로 쉽게 구현할 수 있습니다. 가상DOM을 사용하여 효율도 훨씬 좋습니다.
그렇다면 React에서 언제 직접 DOM을 조작해야 할까요?
state로 해결할 수 없을 때입니다. 주로 다음의 경우입니다.
- 특정 input에 포커스 주기
- 스크롤 박스 조작하기
- Canvas 요소에 그림 그리기 등
useRef로 스크롤 박스 조작하기
이번에 gptea 프로젝트에서 채팅UI를 구현하면서, 최신 메세지가 리스트의 맨 아래에 있어 리렌더링될 때마다 스크롤이 맨 아래에 위치하도록 구현하기 위해 useRef를 사용했습니다. 관련 코드는 매우 짧습니다.
function Div() {
const scrollRef = useRef();
useEffect(() => {
scrollRef.current.scrollTop = scrollRef.current.scrollHeight - scrollRef.current.clientHeight;
}, [])
return <div ref={scrollRef}></div>
}
TypeScript에서 useRef는?
function Div() {
// Ref가 참조할 DOM요소가 HTMLDivElement타입임을 명시
// 이 부분은 return문이 실행되기 전에 실행된다. 즉, DOM이 생성되기 전이므로 DOM요소를 찾으려고 하면 null이다.
// null로 지정하지 않으면 자동으로 undefined가 되는데, 타입이 달라서 오류가 발생한다.
const scrollRef = useRef<HTMLDivElement>(null);
// scrollRef.current는 null일 수 있다.
// 그러므로 처음에는 optional type으로 ?을 주었는데 할당문의 왼쪽은 optional일 수 없다.
// 이런 경우에는 단축평가를 사용한다.
useEffect(() => {
scrollRef.current && scrollRef.current.scrollTop = scrollRef.current.scrollHeight - scrollRef.current.clientHeight;
}, []) //
return <div ref={scrollRef}></div>
}
그러므로 useRef로 DOM을 조작하기 위해 초기값으로 항상 null을 주어야 합니다.
여기서 HTMLDivElement는 제네릭입니다.
자세한 내용은 다음 포스팅에 잘 나와있습니다. (타입스크립트를 좀 더 익히고 다시 공부하기...)
https://tecoble.techcourse.co.kr/post/2022-10-15-function-overloading/
(참고)
고마워 ChatGPT 😄
'개발 > JS, TS, React' 카테고리의 다른 글
TypeScript 열거형, 인터페이스, 타입별칭, 타입추론, 클래스 (0) | 2023.05.31 |
---|---|
TypeScript 프로젝트 환경 구성, 타입 종류 (0) | 2023.05.30 |
React useSelector와 useState를 함께 사용할 때 (0) | 2023.05.23 |
React CORS에러 클라이언트에서 해결하기, proxy 2개 설정하기 (0) | 2023.04.30 |
Redux Toolkit 으로 Redux 더 간편하게 사용하기 (0) | 2023.04.30 |
- Total
- Today
- Yesterday
- 공릉맛집
- 티스토리
- 회고
- 태릉 꼬치
- 태릉 이자카야
- 태릉 술집
- 공릉 이자카야
- 공릉 카페
- 춘천맛집
- 깃허브 데스크탑 로그아웃
- 홍천 삼겹살
- 신불당 술집
- 을지로맛집
- 공릉 술집
- 공릉 맛집
- 티스토리검색
- 공릉 밀크티
- 춘천닭갈비
- 롯데월드 보조배터리
- 이수 맛집
- 태릉삼겹살
- 구글서치콘솔
- Til
- 태릉맛집
- solo project
- 맥 깃허브 데스크탑
- 롯데월드 키오스크
- 공릉 꼬치
- sitemap
- 롯데월드 매직패스 프리미엄
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |