React 기초 정리 7편

정인아·2022년 7월 12일
0

React 기초 정리 7편으로 돌아왔습니다.
이번 편에서는 ref와 useEffect에 대해서 설명 해보려 합니다.

useRef

ref는 reference의 줄임말입니다. 참고라는 뜻이죠
그럼 ref의 역할은 무엇일까요?

일전에 리액트는 선언적 방식으로 작업한다고 말씀드렸습니다.
그리고 바닐자 JS는 명령형 방식이라고도 말씀드렸죠.

명령형 방식에서 DOM 접근을 어떻게 하는지 기억하시나요?

	cosnt input = document.querySelector("input");
    input.value = "test"

네, 위와 같은 방식으로 작업을 합니다.

querySelector외에도 getElementById와 getElementByClass와 같은 명령어도 있습니다.

리액느에서는 querySelector를 쓰지 않습니다.
제가 국비 지원에서 그 이유에 대해서 질문을 했을 때, 답변은

JSX가 렌더링되기전에 querySelector가 해당 DOM을 잡으려고 하면, 간헐적으로 DOM에 접근하지 못한다.

라는 답변을 받았습니다.
해당 답변에 대해서 아직 명확하게 테스트를 해보거나, 사실인지 파악하지 못했습니다.

그렇다면, querySelector를 쓰지 못한다면 해당 DOM에 접근하고 싶을때 무엇을 사용해야할까요?

이게 바로 useRef입니다.

위와 같이 form 태그에 input이 있다고 가정해보겠습니다.
각 input 마다 state를 선언해서 value와 onChange로 input을 관리하려고합니다.

일전에 말씀드렸듯이 onChange와 useState 때문에, 해당 컴포넌트는 키보드를 한글자씩 입력할때마다 렌더링이 되게 됩니다.

input이 수십개라고 가정해보면, 너무 불필요한 렌더링이 반복됩니다.
이 불필요한 렌더링을 막기 위해 useRef 훅을 사용합니다.

위와 같이 연결합니다.
이제 각 input은 useRef훅으로 컨트롤 가능합니다.

해당 부분을 렌더링 후 콘솔로 확인 해보겠습니다.

해당 input이 잡혀있는걸 볼 수 있습니다.
하지만, 객체가 잡혀있죠?
그리고 current라는 키 값이 있습니다.

useRef는 항상 객체를 반환하고 그안에 current에 잡았던 DOM이 있습니다.
DOM 조작도 가능하죠.

그렇지만 여기서 DOM 조작을 하게 되면, React를 사용하는 이유가 줄어듭니다. 여기서 DOM은 리액트에 의해서만 조작되는게 베스트입니다.
즉, 여기서는 DOM을 읽어서 판단할 때 사용하는게 좋습니다.

	console.log(nameInput.current.value)

처럼 말이죠.

state를 사용할지,
useRef를 사용할지에 대해서는 여러분의 판단입니다.

그 때 상황에 맞게 잘 활용하시면, 좀더 효과적인 최적화에 도움이 될겁니다.

useEffect

리액트는 주 목적이 있습니다.
UI를 렌더링하는 것이죠.

그리고 유저의 인터페이스에 따라 UI를 다시 렌더링합니다.
이를 위해 저희는 useState, 이벤트 등과 같은 작업을 해왔죠.

이를 제외하고 이뤄지는 모든 일들을 우리는 side Effects라고 합니다.
서버 통신도 이에 해당하죠.

서버 통신 후, 해당 response를 가지고 state를 업데이트하여, 리렌더링이 이뤄지기도 합니다.

그러면 한가지 살펴볼게요.

위 의 코드를 참고해보면, fetchAPI로 서버 통신 후, 그 결과를 가져옵니다.
그리고 결과를 setData로 state를 업데이트 하죠.

전에 공부했던대로 setData를 호출했으니, App 컴포넌트는 리렌더링 합니다.
그러면 fetchHandle이 다시 실행되고 setData가 또 호출됩니다.

렌더링이 무한대로 반복되겠죠?

이를 방지하기 위해 저희가 사용하는 리액트 훅을 useEffect라고 합니다.

useEffect는 두개의 매개변수를 가집니다.

	useEffect(() => {...}, [ dependencies ]);

바로 실행할 콜백함수와 종속되는 변수를 포함한 배열입니다.
의존성이 연결된 변수의 변화가 감지되면, 콜백함수가 실행됩니다.
물론 처음 렌더링 될 때도, 실행됩니다.

그럼 위의 코드에 useEffect를 입혀보면

이렇게 사용 할 수 있습니다.
useEffect의 두번째 인자에 빈 배열을 넣었습니다.
어느것에도 의존성을 갖지 않기 때문에, 리렌더링이 되더라도 한번만 실행됩니다.

물론 의존성 배열사용에 주의해야합니다.
예를 들어,

위와 같이 data 변수를 의존성에 넣어버리면, useEffect를 사용하기 전과 동일합니다.
fetchHandle 함수가 실행되며 data의 값이 setData로 인해 변화하게 되고, 이 때 의존성을 걸었던 useEffect가 다시 실행되죠.
여전히 무한 렌더링이 됩니다.

그렇기 때문에 deps에 어떤 의존성을 넣을지 고민을 해야합니다.

제가 회사에서 프로젝트 할 경우, 해당 의존성에는 currentPage를 추가했었습니다.
즉, 페이징 처리 되있는 데이터의 경우
페이지가 바뀔 때마다, 서버 통신이 이뤄져야합니다.
이 의존성 인자때문에 useEffect가 힘을 발휘합니다.

이번 정리는 여기까지 입니다.

다음 정리에서는, useReducer와 context API를 다뤄보겠습니다.

profile
프론트엔드 개발자

0개의 댓글