📍 useCallback
- 함수를 기억했다가 재사용하도록 도와주는 훅
- 불필요한 리렌더링을 맊기 위해서
☑️ 리렌더링이란
React의 리렌더링 조건은 간단하게 3가지이다.
1. 자신의 state가 변경될 때
2. 부모 컴포넌트로부터 전달받은 props가 변경될 때
3. 부모 컴포넌트가 리랜더링될 때
☑️ 사용법
const cachedFn = useCallback(fn, [deps1, deps2... ])
- fn : 함수로 React가 첫 렌더링 시에 반환하며, 만약 deps가 바뀌지 않은 경우, 같은 함수를 계속해서 반환하게 돈다.
- deps : 의존성 값으로 fn이 의존하는 값들의 배열이며, 유동적 값(reactive value)이면 어떤 것이든 상관없이 들어갈 수 있으며, 함수가 의존하는 값의 수만큼 개수가 많아질 수 있다. 이 의존성 값이 변경 되었을 때 리렌더링 한다.
const fetchMovieData = useCallback ( () => {
doSomething( );
},
[ 의존성 값],);
☑️ 사용예시 - Row.js
const Row = ({ title, id, fetchUrl }) => {
//title,id,fetchUrl을 props로 가져온 것임
const [movies, setMovies] = useState([]);
//컴포넌트가 렌더링 될 떄 마다 함수도 다시 새롭게 생성되는데 이것이 불필요함으로 콜백함수이용
const fetchMovieData = useCallback(async () => {
const response = await axios.get(fetchUrl);
//console.log('response',response);
setMovies(response.data.results);
}, [fetchUrl]);
useEffect(() => {
fetchMovieData();
}, [fetchMovieData]);
//fetchUrl이 바뀌면 fetchMovieData도 변하기 때문에 다시 호출 해야됨
> fechUrl이 바뀌면 리렌더링해준다
☑️ 사용예시
데이터 fetching과 의존성을 가지는 경우
const Section1 = ({ onProjectClick }) => {
const [popularProjects, setPopularProjects] = useState([]);
// useCallback을 사용하여 fetchPopularProjects 최적화
const fetchPopularProjects = useCallback(async () => {
try {
const response = await axios.get('/api/projects/popular'); // 인기 프로젝트 데이터 요청
setPopularProjects(response.data);
} catch (error) {
console.error('Error fetching popular projects:', error);
}
}, []); // 의존성 배열이 비어 있으므로 컴포넌트가 마운트될 때만 호출됨
useEffect(() => {
fetchPopularProjects(); // 컴포넌트가 마운트될 때 데이터 가져오기
}, [fetchPopularProjects]);
> 의존성 배열을 비어 있으므로 컴포넌트가 처음 렌더링 될때만 생성
> fetchPopularProjects가 변경될 때에만 useEffect가 다시 실행
`useEffect`에서 호출되며, 컴포넌트가 마운트될 때 한 번만 실행됨
☑️ Usecallback을 사용하지 않으면?
- 무한 루프 발생 가능성
- 불필요한 렌더링
- 의존성 관리 문제
📍 Usecallback을 사용해야 될 때
컴포넌트가 자주 리렌더링 되거나 자식 컴포넌트에 함수를 전달해야 될 떄
1. 자식 컴포넌트에 props로 함수 전달 시
자식 컴포넌트에 함수를 props로 전달할 때, 부모 컴포넌트가 리렌더링되면 자식 컴포넌트도 리렌더링될 수 있습니다.특히, 자식 컴포넌트가 React.memo로 최적화되어 있을 경우, useCallback을 사용하여 함수의 참조를 유지하면 불필요한 리렌더링을 방지할 수 있습니다.
2. 외부에서 값을 가져오 API 호출 시 의존성 배열 문제 해결
useEffect에 의존성 배열로 함수를 전달할 때, 그 함수가 매번 새로운 참조값으로 변경되면 무한 루프가 발생할 수 있습니다.useCallback을 사용하면 함수의 참조가 동일하게 유지되어, 의존성이 변경되지 않는 한 useEffect가 불필요하게 재실행되는 것을 방지합니다.
3. custom hook에서 최적화
커스텀 훅을 만들 때, 내부에서 사용하는 함수가 자주 변경되지 않도록 useCallback을 사용하여 최적화할 수 있습니다.이를 통해 훅이 호출될 때마다 함수가 새로 생성되는 것을 방지합니다.
무한 루프를 피하는 대안
함수 바깥에 정의: 의존성으로 사용되는 함수가 바깥에 정의되어 있으면, 컴포넌트가 리렌더링될 때마다 새로운 참조값이 생성되지 않습니다. 그러나 이 방법은 함수가 바뀌어야 할 때 유연성을 잃을 수 있습니다.상태를 직접 사용: 상태 값이 변경될 때마다 그 상태를 직접 사용하는 방식으로, 새로 함수 객체를 생성하지 않고도 상태를 관리할 수 있습니다.
'React > 개념' 카테고리의 다른 글
[리액트] 컴포넌트 및 기초사항 (0) | 2024.01.12 |
---|---|
#6 props - row.js (0) | 2024.01.12 |
$ 사용 (0) | 2024.01.05 |
#4 React 이벤트 처리(리스너, onClick(핸들링 이벤트) (0) | 2024.01.05 |
#2 리액트 컴포넌트 (0) | 2024.01.04 |