useMemo
메모이제이션 된 값을 반환하는 함수.
메모이제이션 이란?
기존에 수행한 연산의 결과값을 어딘가에 저장해두고 동일한 입력이 들어오면 재활용하는 프로그래밍 기법.
효과: 중복 연산을 피할 수 있음 -> 애플리케이션 성능 최적화 가능
// 기본 형태
useMemo(() => function, [dependency])
import { useMemo } from 'react';
function ExampleComponent({ list }) {
const expensiveComputation = useMemo(() => {
// Your expensive computation code goes here
}, [list]);
return <div>{/* Your component JSX */}</div>;
}
useMemo를 쓰는 이유?
겉보기엔 useState랑 큰 차이가 없다.
하지만, 부모 컴퍼넌트 혹은 그 외의 요소로 인하여 리랜더링이 일어난다면, console.log가 계속 찍히게 된다.
const ExampleUseState = () => {
const [count, setCount] = useState(0)
console.log(count)
const onClickBtn = () => {
//count up
}
return (
<div>
<button onClick={onClickBtn}/>
<div/>
)
}
하지만 useMemo를 사용한다면?
const ExampleUseState = () => {
const [count, setCount] = useState (0)
useMemo(() => {
console. log (count)
},[count])
const onClickBtn = () => {
//count up
}
return (
<div>
<button onClick={onClickBtn}/>
<div/>
)
}
count 값이 변했을때에만 console.log 함수가 실행된다.
이렇게 되면 불필요한 연산을 하지 않게 되고, 어플리케이션 최적화를 할 수 있다.
useCallback
메모이 제이션 된 함수를 반환하는 함수
useCallbak(function, [dependency])
import { useCallback } from 'react';
function ExampleComponent({ onEvent }) {
const memoizedCallback = useCallback(() => {
// Your callback code goes here
}, [dependency1, dependency2]);
return <ChildComponent onEvent={memoizedCallback} />;
}
사용 예시)
1. 자식 컴퍼넌트에 함수 전달 할 때
import { useState, useCallback } from 'react';
function ChildComponent({ onRemove, id }) {
return <button onClick={() => onRemove(id)}>Remove</button>;
}
function ParentComponent() {
const [items, setItems] = useState(['Item 1', 'Item 2', 'Item 3']);
const handleRemove = useCallback((itemId) => {
setItems((prevItems) => prevItems.filter((_, index) => index !== itemId));
}, []);
return (
<div>
{items.map((item, index) => (
<div key={index}>
{item} <ChildComponent onRemove={handleRemove} id={index} />
</div>
))}
</div>
);
}
일반 함수를 전달하게 될 경우, 부모 컴퍼넌트가 리렌더링 수정되면 자식 컴퍼넌트도 같이 리렌더링이 일어나게 된다.
하지만 useCallback을 사용할 경우 원치 않는 리랜더링을 방지할 수 있다.
2. 외부 api 호출 할 때
import { useState, useEffect, useCallback } from 'react';
function FetchDataComponent() {
const [data, setData] = useState(null);
const fetchData = useCallback(async () => {
try {
const response = await fetch('https://api.example.com/data');
const result = await response.json();
} catch (error) {
console.error('Error fetching data:', error);
}
}, []);
useEffect(() => {
fetchData().then((result)=> {setData(result)});
}, [fetchData]);
return (
<div>
{data ? (
<div>{/* Render the fetched data */}</div>
) : (
<div>Loading...</div>
)}
</div>
);
}
위의 예제에서 useCallback을 쓰지 않을 경우!
FetchDataComponent가 리렌더링 될 경우 fetchData함수에는 새로운 함수가 할당됨.
그렇게 되면 useEffect의 result 상태값이 바뀌고, state값이 바뀌었기 때문에 다시 리랜더링이 되고 다시 fetchData함수가 새로운 함수가 실행되는 무한루프에 빠지게 된다.
이를 useCallback으로 해결 할 수 있다.
'WIL(Weekly I Learned)' 카테고리의 다른 글
바닐라 자바스크립트에서 jest 환경 셋팅하기 (0) | 2023.10.13 |
---|---|
[TypeScript] Generic, interface , type , enum, Class (0) | 2023.05.22 |
Object.assign({}, 인자) (0) | 2022.09.14 |
[!] CocoaPods could not find compatible versions for pod "Sentry": (0) | 2022.09.13 |
DraggableFlatList long press시 list가 다른 위치로 순간이동 (0) | 2022.09.08 |