


import React, {useState, useRef} from "react";
const UseRefApp2 = () => {
const [renderer,setRenderer] = useState(0);
const countRef = useRef(0);
let countVar = 0;
const doRendering = () => {
setRenderer(renderer + 1);
console.log("rendering")
}
const increaseRef = () => {
countRef.current = countRef.current + 1;
console.log("ref increased", countRef.current);
}
const increaseVar = () => {
countVar = countVar + 1;
console.log("var increased", countVar);
}
const printResult = () => {
console.log(`ref: ${countRef.current}, var: ${countVar}`);
}
return(
<div>
<p>Ref: {countRef.current}</p>
<p>Var: {countVar}</p>
<button onClick={doRendering}>랜더</button>
<button onClick={increaseRef}>Ref 올려</button>
<button onClick={increaseVar}>Var올려</button>
<button onClick={printResult}>Ref Var 올려</button>
</div>
)
}
export default UseRefApp2;
컴포넌트가 리렌더링될 때마다 초기값으로 재설정됨
Hook은 왜 쓰나요?
리액트의 컴포넌트들은 Lifecycle을 가지는데 이것을 제어할 수 있는 method들이 있습니다.
class형 컴포넌트에서만 사용가능한 method들이 있고 리액트 16.8버전부터 새로 도입된 기능으로 함수형 컴포넌트에서도 상태 관리를 할 수 있는 Hooks이 있습니다.
useMemo를 사용하는 주요 이유는 성능 최적화입니다.
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
불필요한 재계산 방지:
렌더링 성능 향상:
참조 동등성 유지:
조건부 계산:
컴포넌트 최적화:
React.memo와 함께 사용하여 컴포넌트의 불필요한 리렌더링을 방지할 수 있습니다.의존성 배열을 통한 제어:
예를 들어, 제공된 코드에서:
const users = useMemo<D.IUser[]>(() =>
D.makeArray(100).map(D.makeRandomUser)
, []);
이 부분은 100명의 랜덤 사용자를 생성하는 작업을 한 번만 수행하고, 이후 리렌더링에서는 이 결과를 재사용합니다. 이는 불필요한 계산을 방지하고 성능을 향상시킵니다.
그러나 useMemo를 과도하게 사용하면 오히려 메모리 사용량이 증가하고 초기 렌더링 시간이 늘어날 수 있으므로, 실제로 성능 향상이 필요한 경우에만 사용하는 것이 좋습니다.
실제 웹사이트 프론트엔드에서 useMemo의 사용 사례를 몇 가지 예시로 설명해드리겠습니다:
복잡한 데이터 필터링 및 정렬:
const filteredAndSortedItems = useMemo(() => {
return items
.filter(item => item.category === selectedCategory)
.sort((a, b) => b.price - a.price);
}, [items, selectedCategory]);```
대규모 상품 목록이 있는 e커머스 사이트에서 카테고리 필터링과 가격순 정렬을 수행할 때 사용할 수 있습니다.
차트 데이터 계산:
const chartData = useMemo(() => {
return salesData.map(sale => ({
date: new Date(sale.date).toLocaleDateString(),
revenue: sale.quantity * sale.price
}));
}, [salesData]);```
대시보드나 분석 페이지에서 차트 데이터를 계산할 때 유용합니다.
폼 유효성 검사:
const isFormValid = useMemo(() => {
return email.includes('@') && password.length >= 8 && name.trim() !== '';
}, [email, password, name]);
회원가입 페이지 같은 곳에서 폼의 유효성을 검사할 때 사용할 수 있습니다.
검색 기능 구현:
const searchResults = useMemo(() => {
return products.filter(product =>
product.name.toLowerCase().includes(searchTerm.toLowerCase())
);
}, [products, searchTerm]);
제품 검색 기능을 구현할 때 사용할 수 있습니다.
페이지네이션 로직:
const paginatedItems = useMemo(() => {
const startIndex = (currentPage - 1) * itemsPerPage;
return items.slice(startIndex, startIndex + itemsPerPage);
}, [items, currentPage, itemsPerPage]);
긴 목록을 페이지별로 나눠 표시할 때 유용합니다.
복잡한 스타일 계산:
const dynamicStyles = useMemo(() => ({
backgroundColor: isDarkMode ? '#333' : '#fff',
color: isDarkMode ? '#fff' : '#333',
fontSize: `${baseFontSize * fontScale}px`
}), [isDarkMode, baseFontSize, fontScale]);
테마나 사용자 설정에 따라 동적으로 스타일을 계산할 때 사용할 수 있습니다.
API 응답 데이터 가공:
const processedData = useMemo(() => {
return apiResponse.map(item => ({
...item,
fullName: `${item.firstName} ${item.lastName}`,
age: new Date().getFullYear() - new Date(item.birthDate).getFullYear()
}));
}, [apiResponse]);
API에서 받아온 데이터를 가공하여 화면에 표시할 때 유용합니다.
이러한 예시들은 계산 비용이 크거나 자주 사용되는 값들에 대해 useMemo를 적용하는 방법을 보여줍니다. 이를 통해 불필요한 재계산을 피하고 애플리케이션의 성능을 향상시킬 수 있습니다.

너무 어렵네요..
그래서 수업시간에 한 내용외에 참고할만한 자료 찾아보기