❓useEffect란
useEffect : React 함수 컴포넌트에서 side effects를 수행하기 위해 사용되는 Hook.
-> (side effects란 컴포넌트의 상태 변화, 외부 API 호출, 구독 및 구독 해제와 같은 작업을 뜻함.)
즉, 어떤 state의 값이 변경되거나, 외부 API를 동기적으로 호출하는 등 리액트 컴포넌트가 렌더링 될 때마다 특정 작업을 실행할 수 있도록 하는 Hook 이다.
💡 useEffect는 component가 mount 되었을 때, unmount 되었을 때, update 되었을 때 특정 작업을 처리할 수 있다.
(useEffect를 통해 기존의 클래스형 컴포넌트에서 사용하던 생명주기(Life cycle) 메소드를 함수형 컴포넌트에서 사용할 수 있게 되었다.)
하지만 생명주기 메소드와 완전히 같은 개념은 아님
useEffect의 기본 형태
=> useEffect( function, deps )
function : 실행하고자 하는 작업
deps : 배열 형태, useEffect내부 코드가 실행되게 하는 의존성 배열
- 의존성 배열
💡 useEffect 내부에서 사용하는 외부 state나 프로퍼티를 의미. 이 배열의 값이 변경될 때만 useEffect가 실행됨.
useEffect의 예시로 사용자의 입력을 받아 state값을 업데이트 하는 경우에 사용자의 입력값이 변경될 때만 API를 호출하고 싶을 때 의존성 배열에 사용자의 입력값을 넣어주면 된다.
useEffect 예시
useEffect(() => {
const fetchData = async () => {
const response = await fetch('API_URL');
const data = await response.json();
setData(data);
};
fetchData();
}, [inputValue]);
- 이와같이 의존성 배열에 값을 넣어주면 해당 값이 변경될 때만 useEffect를 실행시킬 수 있고, 빈 배열을 넣어둔다면 컴포넌트가 처음으로 마운트 되었을때 한번만 실행시킬 수 있다.
클린업 함수
클린업 함수는 useEffect 훅 안에 정의되는 함수로, side effect를 정리하는 역할을 한다. 이 함수는 useEffect 훅에서 side effect가 설정된 컴포넌트가 unmount 되기 직전에 실행된다.
클린업 함수의 기본 형태
: return () => {제거할 로직}
클린업 함수 예시
import React, { useState, useEffect } from 'react';
function ExampleComponent() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('컴포넌트가 마운트됨');
// 이벤트 리스너 추가
document.addEventListener('mousedown', handleClick);
// 클린업 함수 반환
return () => {
console.log('컴포넌트가 언마운트됨');
// 이벤트 리스너 제거
document.removeEventListener('mousedown', handleClick);
};
}, []); // 빈 배열을 전달하여 컴포넌트가 처음 마운트될 때만 실행되도록 함
const handleClick = () => {
setCount(count + 1);
};
return (
<div>
<p>버튼을 클릭한 횟수: {count}</p>
</div>
);
}
export default ExampleComponent;
이 예시와 같이 컴포넌트가 마운트 될 때마다 이벤트 리스너를 추가하고, 컴포넌트가 언마운트 될 때마다 클린업 함수를 통해 이벤트 리스너를 제거하는 작업을 수행한다.
❓useLayoutEffect란?
useLayoutEffect는 useEffect와 유사한 hook이다.
이를 알아보기 위해선 먼저 브라우저 렌더링 과정을 알아야 한다.
Render : DOM Tree 를 구성하기 위해 각 엘리먼트의 스타일 속성을 계산하는 과정
Paint : 실제 스크린에 Layout을 표시하고 업데이트하는 과정
- state의 변화와 같은 이유로 렌더링이 일어날때 먼저 컴포넌트가 렌더 되고, 이후 렌더된 컴포넌트가 화면에 paint된다. useEffect는 이러한 과정 이후에 실행되므로 useEffect 내부에 만약 DOM에 영향을 주는 코드가 있다면 화면의 깜빡임과 함께 사용자가 변화를 알아차리게 된다.
반면 useLayoutEffect는 useEffect와 호출되는 시간이 다르다.
- useLayoutEffect는 컴포넌트가 렌더된 이후 컴포넌트가 화면에 paint되기 전에 실행된다.
- 따라서 DOM에 영향을 주는 코드가 있더라도 화면의 깜빡임이 없다.
사용법은 useEffect와 100%일치하지만 useLayoutEffect는 성능을 저하시킬 가능성이 높기 때문에 사용을 권장하지 않고, 특히 SSR(Server Side Rendering)인 경우에는 useEffect, useLayoutEffect 모두 자바스크립트가 다운로드 되기 전에 실행되지 않는다.
❓useRef란?
useRef는 리액트 훅 중 하나로, DOM 요소에 대한 참조(reference)를 생성하고 관리하는 데 사용된다. useRef를 통해 함수 컴포넌트에서 DOM 요소를 직접 조작하거나 접근할 수 있고 이를 통해 특정 DOM 요소에 직접 접근이 가능하다면, 불필요한 리렌더링을 막을 수 있다.
useRef의 기본 형태
const 변수명 = useRef(초기값)
<input ref= {변수명}/>
useRef 사용 예시
import React, { useRef, useEffect } from 'react';
function ExampleComponent() {
const inputRef = useRef(null);
// 컴포넌트가 마운트될 때 input 요소에 포커스 설정
useEffect(() => {
inputRef.current.focus();
}, []);
const handleInputChange = () => {
console.log('입력된 값:', inputRef.current.value);
};
return (
<div>
<input type="text" ref={inputRef} onChange={handleInputChange} />
</div>
);
}
export default ExampleComponent;
이 예시와 같이 useRef를 사용하여 input 요소에 대한 참조를 생성하고, 포커스를 설정할 수 있다.
useRef를 사용하는 이유
1. state와 같은 저장공간
- useState를 사용해서도 요소에 접근하고, 상태변경을 통해 관리할 수 있지만, useRef를 사용하는 이유는
useState를 사용했을 때 state에 변화가 생기면 렌더링을 하고, 내부 변수들의 값에 변화가 생긴다.
useRef를 사용했을 때는 렌더링이 일어나지 않고, 내부 변수들의 값이 유지된다.
따라서 useRef는 변화를 감지해야 하지만, 그 변화가 렌더링을 일으키진 않아야 할 때 사용한다.
2. DOM요소에 접근
js에서 getElementById, querySelector 와 유사하게 특정 DOM 요소에 직접적으로 접근이 가능하다.
'3주차' 카테고리의 다른 글
state 변경에 따른 리렌더링, useEffect, setTimeout 이해하기 (0) | 2024.11.04 |
---|---|
[React] 리렌더링에 대해 알아보자 (3) | 2024.11.02 |
🙄 리액트에서 배열의 값을 업데이트 하는 방법 (feat. 리액트의 불변성) (1) | 2024.11.02 |
컴포넌트와 Props (0) | 2024.11.02 |
리액트의 flux 패턴 (0) | 2024.11.02 |