(React) useMemo와 useCallback 사용법
* 이 포스팅은 개인적인 복습을 위해 정리한 포스팅입니다.
참고 서적: "리액트를 다루는 기술"
참고 링크:
1. useReducer/useCallback/useMemo 제대로 알고 사용하기
2. useCallback 과 useMemo의 차이점 <11:10 부터 useCallback과 useMemo차이점 설명
포스팅
1. useMemo & useCallback
2. useMemo에 대해서
3. useCallback에 대해서
useMemo & useCallback
> useMemo와 useCallback은 매우 유사하다.
> 내부에서 발생하는 연산을 최적화한다.
> 특정 값이 바뀌었을 때만 연산을 실행하고, 바뀌지 않았으면 이전에 연산했던
결과를 다시 사용하는 방식이다.
> 메모제이션용 메모리가 필요하므로 useMemo와 useCallback을 남용하면 안된다.
useMemo VS useCallback
> useMemo 는 값을 반환
> useCallback은 함수를 반환
useMemo
useMemo 쓰는 형식
const avg = useMemo(() =>{
//내용
},[값]);
< useMemo를 사용하지 않았을 때 코드 >
Average.js
import React, { useState } from 'react';
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState('');
const getAverage = () => {
console.log('평균값 계산 중...');
if (list.length === 0) return 0;
const sum = list.reduce((a, b) => a + b);
return sum / list.length;
};
const onChange = (e) => {
setNumber(e.target.value);
};
const onInsert = () => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber('');
};
return (
<div>
<input value={number} onChange={onChange} />
<button onClick={onInsert}>등록</button>
<ul>
{list.map((value, index) => (
<li key={index}>{value}</li>
))}
</ul>
<div>
<b>평균값:</b> {getAverage()}
</div>
</div>
);
};
export default Average;
App.js
import React from 'react';
import Average from './Average';
const App = () => {
return <Average />;
};
export default App;
<결과>
> 글자 입력 시에도 getAverage함수가 동작하기 때문에 콘솔창에 "평균값 계산중... "이 뜸
> 버튼 클릭시에도 getAverage함수가 동작하기 때문에 콘솔창에 "평균값 계산중..."이 뜸
> 종합적으로, getAverage함수가 필요하지 않은 동작에서도 작동이 됨.
< useMemo를 사용했을 때 코드 >
Average.js
import React, { useState, useMemo } from 'react';
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState('');
const getAverage = useMemo(() => {
console.log('평균값 계산 중...');
if (list.length === 0) return 0;
const sum = list.reduce((a, b) => a + b);
return sum / list.length;
}, [list]); //list값이 업데이트 될때만 실행
const onChange = (e) => {
setNumber(e.target.value);
};
const onInsert = () => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber('');
};
return (
<div>
<input value={number} onChange={onChange} />
<button onClick={onInsert}>등록</button>
<ul>
{list.map((value, index) => (
<li key={index}>{value}</li>
))}
</ul>
<div>
<b>평균값:</b> {getAverage}
{/* useMemo는 값을 반환 */}
</div>
</div>
);
};
export default Average;
> useMemo는 값을 반환 하므로 getAverage() 가 아닌 getAverage로 쓰임.
App.js
import React from 'react';
import Average from './Average';
const App = () => {
return <Average />;
};
export default App;
<결과>
> 첫 렌더링과 값 입력 할때만 렌더링, 즉 [ ] 안에 써준 값 list가 업데이트 될 때만 렌더링.
useCallback
>useMemo를 책에 쓰인 방식으로 바꿔보았습니다.
> onChange와 onInsert함수에 useCallback을 감싸므로, [ ]<-괄호 안의 값이
바뀌었을 때만 함수를 생성해 줍니다.
(* useCallback을 사용하지 않은 경우 리렌더링 될때마다 함수를 새로 만들어 줍니다.)
Average.js
import React, { useState, useCallback, useMemo } from 'react';
const getAverage = (numbers) => {
console.log('평균값 계산 중...');
if (numbers.length === 0) return 0;
const sum = numbers.reduce((a, b) => a + b);
return sum / numbers.length;
};
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState('');
const onChange = useCallback((e) => {
setNumber(e.target.value);
}, []);
const onInsert = useCallback(() => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber('');
}, [number, list]);
const avg = useMemo(() => getAverage(list), [list]);
return (
<div>
<input value={number} onChange={onChange} />
<button onClick={onInsert}>등록</button>
<ul>
{list.map((value, index) => (
<li key={index}>{value}</li>
))}
</ul>
<div>
<b>평균값:</b> {avg}
</div>
</div>
);
};
export default Average;
App.js
import React from 'react';
import Average from './Average';
const App = () => {
return <Average />;
};
export default App;
'웹 > (React)리액트' 카테고리의 다른 글
ClassName 2개 적용하기 (0) | 2021.08.26 |
---|---|
CSS Module: css 클래스 이름 중첩 방지법/ CSS Module사용 이유 (0) | 2021.08.25 |
(React) useReducer 사용법 / useReducer와 이벤트 함께 사용하기 (0) | 2021.08.24 |
(React) 리액트 useEffect 사용법 (0) | 2021.08.23 |
(React) 리액트: 초간단 리스트 작성 기능 구현하기(간단함)/이벤트 핸들링 및 useRef, useState 사용 (0) | 2021.08.22 |
댓글