[ UseMemo ]
함수의 결과를 메모이제이션.
=> 의존값이 변경되지 않으면 함수의 재연산 없이 메모제이션된 값을 반환.
아래처럼 배열 arr에 대해, 배열의 합을 구하는 함수 sum 이 있을때,
const [arr, setArr] = useState([1, 2, 3, 4, 5]);
const [count, setCount] = useState(0);
// 배열합
const sum = arr.reduce((a, b) => a + b);
console.log("배열합계산");
// 카운트클릭
const handleClick = () => {
setCount((prev) => prev + 1);
};
// 배열값추가
const addArr = () => {
setArr((prev) => {
let copy = [...prev];
let max = Math.max(...copy);
return [...prev, max + 1];
});
};
// 배열값변경
const changeArr = () => {
setArr((prev) => {
let copy = [...prev];
copy[copy.length - 1] += 1;
return [...copy];
});
};
return (
<>
<div>
<div>배열 : {arr}</div>
<div>배열합 : {sum}</div>
<div>
<button onClick={handleClick}>카운트 : {count}</button>
</div>
<div>
<button onClick={addArr}>배열값추가</button>
<button onClick={changeArr}>배열값변경</button>
</div>
</div>
</>
);
'카운트' 버튼 클릭 => count증가, sum 함수 실행.
'배열값추가' 버튼 클릭 => sum 함수 실행.
'배열값변경' 버튼 클릭 => sum 함수 실행.
count가 state값으로 지정되어 있어 버튼을 누를때마다 sum함수도 함께 실행되고 불필요한 같은 연산을 반복하게 된다.
sum함수가 배열값이 추가/변경될때만 실행되도록 useMemo 적용.
* UseMemo *
첫번째인자 => 연산결과를 반환하는 함수 (sum)
두번째인자 => 의존성배열 (arr, arr.length) _ 이 값들이 변경될때만 함수 실행(재연산)
* 배열은 참조객체이기 때문에 배열 요소값을 직접 변경하는 경우에는(ex) arr[0] = 0) 배열의 변경사항을 감지하지 못할 수 있다. 따라서 arr.length도 의존성으로 추가. 아래 예시에서는 arr참조값을 바꿔줬기 때문에 없어도 잘 됨. 그냥 참고
const [arr, setArr] = useState([1, 2, 3, 4, 5]);
const [count, setCount] = useState(0);
// ********************* UseMemo *********************
const sum = useMemo(() => {
console.log("배열합계산");
return arr.reduce((a, b) => a + b);
}, [arr, arr.length]);
// 카운트클릭
const handleClick = () => {
setCount((prev) => prev + 1);
};
// 배열값추가
const addArr = () => {
setArr((prev) => {
let copy = [...prev];
let max = Math.max(...copy);
return [...prev, max + 1];
});
};
// 배열값변경
const changeArr = () => {
setArr((prev) => {
let copy = [...prev];
copy[copy.length - 1] += 1;
return [...copy];
});
};
return (
<>
<div>
<div>배열 : {arr}</div>
<div>배열합 : {sum}</div>
<div>
<button onClick={handleClick}>카운트 : {count}</button>
</div>
<div>
<button onClick={addArr}>배열값추가</button>
<button onClick={changeArr}>배열값변경</button>
</div>
</div>
</>
);
'카운트' 버튼 클릭 => count증가, sum 함수 실행.
'배열값추가' 버튼 클릭 => sum 함수 실행.
'배열값변경' 버튼 클릭 => sum 함수 실행.
[ UseCallback ]
콜백함수를 메모제이션
=> 의존값이 변경되지 않으면 함수의 재생성 없이 메모제이션된 함수를 반환.
'카운트' 버튼을 클릭하면 count값이 증가되는 handleClick() 함수에 대해서,
const [arr, setArr] = useState([1, 2, 3, 4, 5]);
const [count, setCount] = useState(0);
// 배열합
const sum = useMemo(() => {
return arr.reduce((a, b) => a + b);
}, [arr, arr.length]);
// 카운트클릭
const handleClick = () => {
setCount((prev) => prev + 1);
};
// ************* 카운트클릭 함수 생성확인 *************
const copyFunc = useRef(null);
if (copyFunc.current != handleClick) {
console.log("새로 생성된 함수");
copyFunc.current = handleClick;
} else {
console.log("기존 함수");
}
// 배열값추가
const addArr = () => {
setArr((prev) => {
let copy = [...prev];
let max = Math.max(...copy);
return [...prev, max + 1];
});
};
// 배열값변경
const changeArr = () => {
setArr((prev) => {
let copy = [...prev];
copy[copy.length - 1] += 1;
return [...copy];
});
};
return (
<>
<div>
<div>배열 : {arr}</div>
<div>배열합 : {sum}</div>
<div>
<button onClick={handleClick}>카운트 : {count}</button>
</div>
<div>
<button onClick={addArr}>배열값추가</button>
<button onClick={changeArr}>배열값변경</button>
</div>
</div>
</>
);
어떤 버튼을 클릭해도 handleClick함수가 재생성된다. ( 콘솔창에 "새로 생성된 함수" 출력 )
불필요한 함수 생성을 막기 위해 UseCallback 사용.
* UseCallback *
첫번째인자 => 콜백 함수 (handleClick)
두번째인자 => 의존성배열 ( [ ] ) _ 이 값들이 변경될때만 함수 생성, 빈 값인 경우 초기 렌더링 시 한번만 생성
const [arr, setArr] = useState([1, 2, 3, 4, 5]);
const [count, setCount] = useState(0);
// 배열합
const sum = useMemo(() => {
return arr.reduce((a, b) => a + b);
}, [arr, arr.length]);
// ********************* UseCallback *********************
const handleClick = useCallback(() => {
setCount((prev) => prev + 1);
}, []);
// ************* 카운트클릭 함수 생성확인 *************
const copyFunc = useRef(null);
if (copyFunc.current != handleClick) {
console.log("새로 생성된 함수");
copyFunc.current = handleClick;
} else {
console.log("기존 함수");
}
// 배열값추가
const addArr = () => {
setArr((prev) => {
let copy = [...prev];
let max = Math.max(...copy);
return [...prev, max + 1];
});
};
// 배열값변경
const changeArr = () => {
setArr((prev) => {
let copy = [...prev];
copy[copy.length - 1] += 1;
return [...copy];
});
};
return (
<>
<div>
<div>배열 : {arr}</div>
<div>배열합 : {sum}</div>
<div>
<button onClick={handleClick}>카운트 : {count}</button>
</div>
<div>
<button onClick={addArr}>배열값추가</button>
<button onClick={changeArr}>배열값변경</button>
</div>
</div>
</>
);
초기 렌더링 시 => handleClick 함수 생성. ( 콘솔창에 "새로 생성된 함수" 출력 )
버튼 클릭 => 기존 handleClick 함수 사용. ( 콘솔창에 "기존 함수" 출력 )
* UseCallback 의존성 배열
=> 함수의 실행 결과에 직접적으로 영향을 끼치는 값으로 지정.
* UseCallback 이 필요한 경우
- 부모 컴포넌트의 렌더링에 의한 자식 컴포넌트의 렌더링을 방지하고자 할 때.
- 계산 비용 / 호출 비용이 큰 함수의 최적화.
'React > 공부공부' 카테고리의 다른 글
[React] Redux 라이브러리 (createReducer) (0) | 2024.08.30 |
---|---|
[ React / ag-grid ] grid 내부에 버튼 넣기 (0) | 2024.08.21 |
[React] Debounce 를 활용한 검색기능. (0) | 2024.06.22 |
[React] 리렌더링 조건 (0) | 2024.06.15 |
[ React / ag-grid ] 관련정리 (0) | 2024.05.25 |