리액트를 공부하면서 document.queryselector를 이용한 코드를 본적이 없었다.
그래서 원래 사용하면 안되는 거구나라고 자연스럽게 생각하고 있었다.
하지만 최근에 사용하기도 한다는걸 알게되었고, 왜 사람들이 지양하는지 알아보게 되었다.
그러한 이유는 우선 리액트의 virtual dom과 관련이 있다.
가상돔은 말 그대로 가짜돔이다. 브라우저는 렌더링 시에
파싱 -> 렌더트리생성 -> 레이아웃 -> 페인트
위와 같은 과정을 거치게 되는데 페이팅을 할때마다 돔을 새로 그리게 되면 1초에도 렌더링이 수백번 일어나게 되고, 그과정을 줄이고 싶어서 가상돔을 사용하게 되었다. 돔을 복사해서 메모리에 넣어놨다가 페인팅시에 한번에 방영하게 된다. 이를 가상돔이라고 부른다.
React에서 document.querySelector를 사용하게되면, 실제 DOM의 요소를 가져오게 된다. 따라서 실제돔보다는, React가 제어하고있는 Virtual DOM 안에 있는 요소가 더 신뢰할만하다.
-->DOM API로 Real DOM에 있는 친구를 집었는데, 이게 현재 Virtual DOM을 통해 Real DOM에 존재하는 친구인지 아닌지 확신할 수 없다는 것!
예를 들어, Dialog 컴포넌트에서 open()과 close() 메서드를 두는 대신, isOpen이라는 prop을 넘겨줘야 한다.
state제어의 어려움
React가 State를 컨트롤(제어)하고 있다. 만약 이러한 React 시스템을 벗어나 DOM을 직접적으로 건드리게되면 이 내용들은 React가 제어하는 영역에서 벗어나게 되고, 이렇게 React의 제어를 벗어나게 되면, React에서 제공하는 이점들을 사용할 수 없게 된다.
디버깅이 어려워짐
React의 Lifecycle에 맞추어 DOM Element를 가져오지 못해 가져온 DOM Element를 신뢰할 수 없어지는 문제가 발생한다. 이렇게 데이터를 어디에서 어떻게 조작하고 있는지 예측하기 어렵기 때문에 디버깅 또한 어려워진다.
ref : render 메서드에서 생성된 DOM 노드나 React 엘리먼트에 접근하는 방법을 제공한다.
-->쉽게 말하자면 돔에 달아주는 이름표와 같다.
필요할때 이 이름표를 꺼내 불러주면 된다.
ref를 사용하는 경우는 아래와 같다.
ref의 바람직한 사용 사례는 다음과 같습니다.
- 포커스, 텍스트 선택영역, 혹은 미디어의 재생을 관리할 때.
- 애니메이션을 직접적으로 실행시킬 때.
- 파티 DOM 라이브러리를 React와 같이 사용할 때.
- 선언적으로 해결될 수 있는 문제에서는 ref 사용을 지양하세요.
const nameRef = useRef(); //ref 선언 (돔에 이름을 만들어준다.)
let list = {
id:todoList[todoList.length - 1].id + 1,
title: nameRef.current.value, //이름표로 값을 꺼낸다.
body: todoBody,
isDone: false,
};
<InputBox
ref={nameRef} //해당돔에 이름표를 달아준다.
value={todoTitle}
onChange={onChange}
type="text"
name="todoTitle"
required
/>
</TitleBox>
하지만
ref는 정말 필요로 할 때가 아닌 이상은 ref를 사용하는 것을 지양하도록 권고하고 있다.(공식 문서에서 말이다.) 왜 그러는 걸까?
그 이유는 DOM을 조작하는 이벤트 자체가 우선 무겁다는 점이다. 실제 DOM에 접근하려면 DOM 자체의 데이터를 받아와야하기 때문에 거기서부터 오는 정보의 무게감이 들 수 밖에 없다.
아울러, React는 최대한 그런 DOM을 건드리지 않기 위해 가상 DOM을 활용하고 있다.그러다보니 ref는 그런 실제 DOM의 정보를 참고하기 위해 쓰이는 용도이므로 되도록이면 필요할 때 빼고는 지양하는 게 좋다고 한다.
내가 ref를 주로 쓰는 곳은 input태그의 값을 갖고 오기 위해 onchange함수를 사용할때이다. onchange에서 발생하는 과한 렌더링을 막기위함인데
하도 쓰지 말라고 하니깐 쓰기가 망설여진다.
이러한 고민들에 대해 기술매니저님께 조언을 구했더니 input태그에서 값만 가져오는 경우라면 ref를 써도 무관하다. 하지만 다른 조건이나 함수가 붙는 경우라면 보통은 onchange를 사용한다고 한다. 보통은 어딘가에 종속되거나, 섞여있기보다는 컴포넌트로 따로 떨어져 있기 때문에 해당 부분만 렌더링이 되어서라고 하셨다. 상황에 맞게 잘 쓰면 될거같다. 만약 onchange때문에 다른부분도 렌더링이 되는 경우라면 usememo라던가 다른 아이템들을 사용하면 되니 상황에 맞게 잘 사용해 보자!
참고자료
https://ko.reactjs.org/docs/refs-and-the-dom.html
https://mingule.tistory.com/61