useMemo 적용 전,
렌더링 될때마다 함수가 호출되는데, 같은 이름의 함수가 호출되도 렌더링되면 js메모리에서 다른 주소를 참조하기 때문에 엄연히 다른 object임
모든 함수가 다 렌더링 되는 경우도 다 다른 object를 참조하게 되서 그런거임
이런경우를 방지하기 위해 위의 2가지를 사용
import React, { useState } 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
}
export default function Average() {
const [list, setList] = useState([])
const [number, setNumber] = useState("")
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(list)}
</div>
</div>
)
}
onChange함수에서 number state가 변하면서 getAverage함수도 계속 렌더링 된다.
(불필요하게 렌더링되고 있음. 평균값 나올때만 실행하면되는데!)
useMemo 적용 후,
등록버튼을 누를때만 호출된다.
import React, { useState, 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
}
export default function Average() {
const [list, setList] = useState([])
const [number, setNumber] = useState("")
const onChange = (e) => {
setNumber(e.target.value)
}
const onInsert = () => {
const nextList = list.concat(parseInt(number))
setList(nextList)
setNumber("")
}
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>
)
}
첫번째 파라미터 : 콜백함수
두번째 파라미터 : dependency
useMemo 는 result 값을 기억하고 (인자 활용 X : 값만 받기 때문)
useCallback은 콜백함수 자체를 기억한다. (인자 활용 O : 함수이기 때문)