💡 SideEffect란?
컴포넌트 그리기와는 직접적인 관계가 없는 처리
ex) 화면을 그린 DOM 수동 변경, 로그 출력, 타이머 설정, 데이터 취득 등
useEffect
- sideEffect를 실행하기 위해 사용하는 훅
- useEffect()를 사용하면, props나 state가 업데이트되고, 다시 그리기가 완료된 후 처리가 실행
- 의존성 배열을 지정해서, 특정 데이터가 변화할 때만 처리하도록 설정 가능
다음 코드는 useEffect를 사용한 예제입니다.
Clock 컴포넌트는 현재 시각을 표시하고, 1초마다 시간이 업데이트되며, 드롭다운 메뉴를 선택해서 시각 표기를 변경할 수 있습니다. 시각 표기 설정은 로컬 스토리지에 저장됩니다. 리로드 뒤에는 로컬 스토리지에 저장된 데이터를 읽어, 가장 마지막에 선택한 값을 표시합니다.
import { useState, useEffect } from 'react';
// 타이머가 호출되는 주기를 1초로 한다
const UPDATE_CYCLE = 1000
// 로컬 스토리지에서 사용하는 키
const KEY_VALUE = 'KEY_LOCALE';
enum Locale {
US = 'en-US',
KR = 'ko-KR',
}
const getLocaleFromString = (text: string) => {
switch (text) {
case Locale.US:
return Locale.US;
case Locale.KR:
return Locale.KR;
default:
return Locale.US;
}
}
const Clock = () => {
const [timestamp, setTimestamp] = useState(new Date());
const [locale, setLocale] = useState(Locale.US);
// 타이머를 설정하기 위한 sideEffect
useEffect(() => {
// 타이머 셋
const timer = setInterval(() => {
setTimestamp(new Date());
}, UPDATE_CYCLE);
// 클린업 함수를 전달하고, 언마운트 시에 타이머를 해제한다.
return () => {
clearInterval(timer)
}
// 초기 그리기 시에만 실행한다.
}, []);
// 로컬 스토리지에서 값을 로딩
useEffect(() => {
const savedLocale = localStorage.getItem(KEY_VALUE);
if (savedLocale !== null) {
setLocale(getLocaleFromString(savedLocale));
}
}, []);
// 로케일이 바뀌었을 때 로컬 스토리지에 값을 저장
useEffect(() => {
localStorage.setItem(KEY_LOCALE, locale);
// 의존 배열에 로케일을 전달하고, 로케일이 변할 때마다 실행
}, [locale]);
return (
<div>
<p>
<span id="current-time-label">현재 시각</span>
<span>:{timestamp.toLocaleString(locale)</span>
<select
value={locale}
onChange={(e) => setLocale(getLocaleFromString(e.target.value))}>
<option vlaue="en-US">en-US</option>
<option vlaue="ko-KR">ko-KR</option>
</select>
</p>
</div>
);
}
useLayoutEffect
- useEffect와 마찬가지로 sideEffect를 실행하기 위한 훅이지만, 실행 시점이 다름
- useEffect와 달리 DOM이 업데이트된 후, 화면에 실제로 그려지기 전에 실행
다음 코드는 useLatyoutEffect를 사용한 예제입니다.
위에서 사용한 useEffect의 예제에서 2번째 useEffect를 수정하였습니다.
import { useState, useEffect } from 'react';
// 타이머가 호출되는 주기를 1초로 한다
const UPDATE_CYCLE = 1000
// 로컬 스토리지에서 사용하는 키
const KEY_VALUE = 'KEY_LOCALE';
enum Locale {
US = 'en-US',
KR = 'ko-KR',
}
const getLocaleFromString = (text: string) => {
switch (text) {
case Locale.US:
return Locale.US;
case Locale.KR:
return Locale.KR;
default:
return Locale.US;
}
}
const Clock = () => {
const [timestamp, setTimestamp] = useState(new Date());
const [locale, setLocale] = useState(Locale.US);
// 타이머를 설정하기 위한 sideEffect
useEffect(() => {
// 타이머 셋
const timer = setInterval(() => {
setTimestamp(new Date());
}, UPDATE_CYCLE);
// 클린업 함수를 전달하고, 언마운트 시에 타이머를 해제한다.
return () => {
clearInterval(timer)
}
// 초기 그리기 시에만 실행한다.
}, []);
// 리렌더링 할 때마다 localstorage의 값을 읽기 전에 초기값인 US가 표시되어 살짝
// 이상하게 보임,
// useLayoutEffect를 사용하면 초기 화면에 반영되기 전에 localstorage로부터
// 데이터를 읽으므로 이런 현상을 없앨 수 있음
// 하지만 ㅕuseLayoutEffect로 실행하는 처리는 동기적으로 실행되므로, 무거운 처리를
// 실행하면 화면 그리기가 지연되므로 주의
useLayoutEffect(() => {
const savedLocale = localStorage.getItem(KEY_VALUE);
if (savedLocale !== null) {
setLocale(getLocaleFromString(savedLocale));
}
}, []);
// 로케일이 바뀌었을 때 로컬 스토리지에 값을 저장
useEffect(() => {
localStorage.setItem(KEY_LOCALE, locale);
// 의존 배열에 로케일을 전달하고, 로케일이 변할 때마다 실행
}, [locale]);
return (
<div>
<p>
<span id="current-time-label">현재 시각</span>
<span>:{timestamp.toLocaleString(locale)</span>
<select
value={locale}
onChange={(e) => setLocale(getLocaleFromString(e.target.value))}>
<option vlaue="en-US">en-US</option>
<option vlaue="ko-KR">ko-KR</option>
</select>
</p>
</div>
);
}
'Frontend > React.js' 카테고리의 다른 글
[React]state를 업데이트를 위한 두 가지 방법 (1) | 2024.12.29 |
---|---|
[React] 여러 클래스명을 지정하는 라이브러리 classnames (1) | 2024.12.23 |
[React] 문자열로 이루어진 태그를 페이지에 반영하는 법 (0) | 2024.12.18 |
[React] Redux-toolkit 사용법 (0) | 2024.08.13 |
[React] 리액트에서의 타입스크립트 (0) | 2024.08.13 |