memoization , custom hook 가 없어도 기능은 잘 되어야한다.
최적화가 없이 작동이 안 된다면, 잘못 작성한 코드일 가능성이 높다
-최적화는 마지막에 진행
memoization
불필요한 리렌더링 막기
*캐싱 : 자주 사용하는 데이터를 저장해두고, 필요할때 빠르게 접근할 수 있게 하기 위해 사용
웹개발에서의 사용 예 :
- 첫 렌더링 시 불러온 데이터를 브라우저에 캐싱해두고, 필요할 때 재사용( 브라우저 캐싱)
- 캐싱은 자주 사용하는 데이터를 더 빠르게 접근할 수 있는 위치에 저장한다
react 공식 문서 - useContext
https://react-ko.dev/reference/react/useContext
useContext – React
The library for web and native user interfaces
react-ko.dev
1. memo(컴포넌트 캐싱)
부모 컴포넌트 리렌더링 시 props 변화 없는 자식 컴포넌트도 렌더링 될 경우, 그 때를 막기 위해 주로 사용한다.
- 필요한 경우에만 사용. (memoization도 결국 메모리를 차지하는 것이기때문에, 불필요하게 사용하면 메모리 낭비)
props 값이 변하지 않는다는 전제 하에 적용
사용법 1
component의 함수 부분 감싸기
import { memo } from "react";
const List = memo(({ items }) => {
console.log("List component rendered");
return (
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
);
});
export default List;
사용법 2
export 할 때에 감싸기(이 방식이 더 편리하고 좋아보인다)
import { memo } from "react";
const List = ({ items }) => {
console.log("List component rendered");
return (
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
);
};
export default memo(List);
2. useMemo(값을 캐싱, 함수 캐싱도 가능)
계산 비용이 많이 드는 함수를 rendering path 내에서 사용해야할 때
계산 시간이 1ms 이상이면 계산 비용이 비싸다고 판단
- console.time(),console.timeEnd() 로 작동 시간 확인 가능 -괄호 속에 같은 이름을 문자열로 넣어 함수를감싸줘야한다)
- for, filter, map 등의 가동 시간이 1ms가 넘어가면 적용 - react에서 권장하는 방식)
ex. 반복문
conse doExpensiveWork = useMemo(()=>{}
=> 첫 렌더링시에만 작동시켜 값을 담고, 다시 실행시키지 않는다
ex.
const App = () => {
const [input, setInput] = useState("");
const [items, setItems] = useState(["Item 1", "Item 2", "Item 3"]);
const handleInputChange = (event) => {
setInput(event.target.value);
};
const addItem = () => {
setItems((prevItems) => [...prevItems, input]);
setInput("");
};
//items가 변경될 때만 해당 함수 실행
const filteredItems = useMemo(() => {
return items.filter((item) => item.toLocaleLowerCase().includes("item"));
}, [items]);
return (
<div>
<h1>Item List</h1>
<input type="text" value={input} onChange={handleInputChange} />
<button onClick={addItem}>Add Item</button>
<List items={filteredItems} />
</div>
);
};
3. useCallback(함수 자체를 캐싱)
- useMemo 사용으로도 되지만, 가독성 등을 높이기 위해 이해하고있어야한다
custom hook에 함수가 있을 경우 useCallback으로 감싸주는 걸 리액트 공식 문서에서 권장함
custom hook :
https://ko.react.dev/learn/reusing-logic-with-custom-hooks
커스텀 훅 이름은 use 로 시작
재사용하는 커스텀 훅도 useCallback으로 감싸준다
(리액트 권장 내용)
사용 이유
- 비지니스 로직 재사용
- 컴포넌트 가독성 향상
- 유지보수성 향상
사용 예시
//custom hook
// TODO: 이곳에 커스텀훅 작성하세요.
import { useEffect, useState } from "react";
function useFetch() {
const [title, setTitle] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch("https://jsonplaceholder.typicode.com/todos/1");
console.log("response:", response);
if (!response.ok) {
//응답 실패시,작동 멈추고 콘솔에 "Network 오류"
throw new Error("Network 오류");
}
const result = await response.json();
setTitle(result.title);
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
};
fetchData();
}, []);
if (loading) return <h1>Loading...</h1>;
if (error) return <h1>Error: {error.message}</h1>;
return { title };
}
export default useFetch;
//App.jsx
import React from "react";
import useFetch from "./hooks/useFetch";
const App = () => {
const { title } = useFetch();
return (
<div>
<h1>Data Fetching Example</h1>
<p>{title}</p>
</div>
);
};
export default App;
'개념,기능 정리' 카테고리의 다른 글
비동기 처리-promise, async/await (0) | 2024.06.10 |
---|---|
Supabase (0) | 2024.05.30 |
Yarn, Vite로 빌드 후 리액트 깃허브 배포하기 (0) | 2024.05.29 |
redux tool kit (0) | 2024.05.28 |
redux(2)-redux사이클확인,dispatch,action creator,action values, paload, Ducks패턴 (0) | 2024.05.26 |