/* 정보 전달 목적의 글 보다는 공부하면서 기억하기 위해 적는 글입니다.
따라서 깊이가 얕으며, 잘못된 정보가 있을 수 있습니다. */
useCallback
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
첫 번째 파라미터 : 생성하고 싶은 함수
두 번째 파라미터 : deps 배열 (해당 배열의 어떤 값이 바뀌었을 때 함수를 생성해야하는지를 명시함.)
비어있는 배열을 넣을 경우, 컴포넌트가 렌더링될 때 만들었던 함수를 계속해서 재사용한다.
즉, 컴포넌트가 처음 렌더링될 때만 함수를 생성한다.
하지만 내용이 있는 배열을 넣을 경우, 해당 배열이 바뀌었을 때만 함수를 생성한다.
따라서 함수 내부에서 상태 값에 의존해야하는 경우에는 두 번째 파라미터 안에 포함시켜 줘야한다.
useMemo와 상당히 비슷한 함수로, 이 역시 렌더링 성능을 최적화하기 위해 사용한다.
useMemo와 비교를 하자면, 다음과 같다.
useCallback(fn, deps) 은 useMemo(() => fn, deps) 와 같습니다
useMemo 는 특정 결과값을 재사용 할 때 사용하는 반면,
useCallback 은 특정 함수를 새로 만들지 않고 재사용하고 싶을때 사용합니다.
useCallback
import React, { useState, useCallback, useMemo } from "react";
const getAverage = numbers => {
if (numbers.length === 0) return 0;
const sum = numbers.reduce((a, b) => a + b);
return sum / numbers.length;
}
const MyComponent = () => {
const [number, setNumber] = useState();
const [list, setList] = useState([]);
const onChange = useCallback(e => {
setNumber(e.target.value)
}, []);
const onClick = useCallback(() => {
const newList = list.concat(parseInt(number))
setList(newList);
setNumber();
}, [number, list]);
const avg = useMemo(() => getAverage(list), [list]);
return (
<div>
<input name="number" value={number} onChange={onChange}></input>
<button onClick={onClick}></button>
<h2>{avg}</h2>
</div>
)
}
export default MyComponent;
useCallback의 느낌
import React, { useState } from 'react'
import './TodoInsert.scss'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faPlus } from '@fortawesome/free-solid-svg-icons'
const TodoInsert = () => {
const [value, setValue] = useState('');
const onChange = (e) => {
setValue(e.target.value);
}
return (
<form className="TodoInsert">
<input value={value} onChange={onChange} placeholder="할 일을 입력하세요."></input>
<button type="submit">
<FontAwesomeIcon icon={faPlus} />
</button>
</form>
)
}
export default TodoInsert;
위와 같이 코드를 작성하면, input의 값이 변할 때 마다(==리렌더링을 할 때 마다) onChage 함수가 새로 만들어진다.
따라서 렌더링이 자주 발생하거나, 렌더링해야하는 컴포넌트의 개수가 많아지면 최적화를 해줘야한다.
import React, { useCallback, useState } from 'react'
import './TodoInsert.scss'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faPlus } from '@fortawesome/free-solid-svg-icons'
const TodoInsert = () => {
const [value, setValue] = useState('');
const onChange = useCallback(e => {
setValue(e.target.value);
}, []);
return (
<form className="TodoInsert">
<input value={value} onChange={onChange} placeholder="할 일을 입력하세요."></input>
<button type="submit">
<FontAwesomeIcon icon={faPlus} />
</button>
</form>
)
}
export default TodoInsert;
반면에 useCallback을 쓰면, 처음에 만들었던 함수를 계속해서 가져다 쓴다.
결론
useCallback 역시 값이 변경되었을 때 원하는 함수를 수행하도록 하는 함수다.
useMemo와 비교를 해보자면, useMemo는 특정 결과값을 메모이제이션하는 것이고useCallback은 함수를 메모이제이션하는 것인 것 같다.
사실 아직 이해가 잘 안돼서 내일 회의 때 물어볼 예정이다.
'NewLearn > React' 카테고리의 다른 글
프로젝트 초기 셋팅하기 (CRA와 Backend 분리하기) (0) | 2021.12.20 |
---|---|
[React] useMemo() (0) | 2021.05.04 |
[React] useReducer()* (0) | 2021.05.03 |
[React] useEffect() * (0) | 2021.05.03 |
[React] map, filter를 이용한 예제 (0) | 2021.05.03 |