1. useMemo
리액트 성능 최적화
함수형 컴포넌트는 함수이다
jsx를 반환하는 함수
컴포넌트가 렌더링 되는것은 그 컴포넌트 함수를 호출해서 실행되는 것을 말함
함수가 실행 될 때 함수 내부에 선언된 표현식(변수, 다른 함수)도
다시 선언되어 사용됩니다.
컴포넌트는 자신의 state가 변경되거나 부모에게서 받는 props가
변경될 때 마다 리렌더링 됩니다
예를들어 state.props가 여러가지라면
state1, state2, state3
state1을 리렌더링 시켜주었는데
state2, state3 도 리렌더링 된다면??
원하는 props만 리렌더링시켜주기 위해 useMemo와 useCallback 함수가 있다
useMemo 란?
컴퍼넌트 성능 최적화에 사용
함수니깐 여기에 정의된 변수도 다시 리렌더링 (재사용 가능)
useMemo의 Memo는 ------> memoization 을 뜻함
memoization는 동일한 값을 리턴하는 함수를 반복적으로 호출해야한다면 처음 값을
계산할때 그 값을 메모리 저장해서 필요할때만 계산하지 않고 메모리에서 꺼내서 재사용하는 기법
자주 필요한 값을 처음 계산할때 캐시에 저장을 해두어 값이 **필요할때마다
계산하지 않고 캐시에서 꺼내서 재사용
구문)
*deps --->의존성 배열 (dependency array)
useMemo(() => {
return value;
},[deps])
원하는 변수만 리렌더링해주고 싶은데 .... 두 매개변수 중에 하나만 변경되도 다 같이 리랜더링 된다
*함수형 컴포넌트는 렌더링을 할경우 ---> component함수가 호출되고 ---> 모든 내부 변수는 초기화됨
↓↓↓↓↓↓↓
function calculate(value){
return value+1;
}
function FunComponent({value, text}){ //객체 구조분해 할당
const number = calculate(value);
return(
<div>
{number}
{text}
</div>
)
}
useMemo 실습1 (codeSandBox 하단에 콘솔창 확인)
useMemo 함수 사용하여 각각 리렌더링 시켜 number 관련 콘솔, text 관련 콘솔 내용 따로 출력되게함
App.js
import { useState } from "react";
import ShowState from "./component/ShowState";
function App() {
const [number, setNumber] = useState(0);
const [text, setText] = useState("");
const increaseNumber = () => {
setNumber(number + 1);
};
const decreaseNumber = () => {
setNumber(number - 1);
};
const onChange = (e) => {
setText(e.target.value);
};
return (
<div className="App">
<div>
<button onClick={increaseNumber}>+1</button>
<button onClick={decreaseNumber}>-1</button>
<input type="text" paaceholder="lastname" onChange={onChange} />
</div>
<ShowState number={number} text={text} />
</div>
);
}
export default App;
ShowState.js
import React, { useMemo } from "react";
const getNumber = (number) => {
console.log("숫자가 변동되었습니다.");
return number;
};
const getText = (text) => {
console.log("글자가 변동되엇습니다.");
return text;
};
const ShowState = ({ number, text }) => {
const showNumber = useMemo(() => getNumber(number), [number]);
const showText = useMemo(() => getText(text), [text]);
return (
<div>
{showNumber}
<br />
{showText}
</div>
);
};
export default ShowState;
useMemo 실습2 (codeSandBox 하단에 콘솔창 확인)
useMemo함수 사용하여 숫자 변경할때는 console창에 출력내용 안뜨고
나라 이동 버튼 클릭시 console창 출력되게 함
App.js
import MemoComponent from "./component/MemoComponent";
function App() {
return (
<div className="App">
<MemoComponent />
</div>
);
}
export default App;
MemoComponent.js
import React, { useEffect, useMemo, useState } from "react";
const MemoComponent = () => {
const [number, setNumber] = useState(0);
const [isKorea, setIsKorea] = useState(true);
//원시형타입 vs 객체타입
/* const location = {
country: isKorea ? "한국" : "외국"
} */
const location = useMemo(() => {
return {
country: isKorea ? "한국" : "외국"
};
}, [isKorea]);
//useEffect(콜백함수,[desp])
//useEffect ======> 마운트될때, 업데이트(리렌더링), 언마운트일때
useEffect(() => {
console.log("풍풍풍, userEffect호출");
}, [location]);
return (
<div>
<h2>좋아하는 숫자는?</h2>
<input
type="number"
value={number}
onChange={(e) => setNumber(e.target.value)}
/>
<h2>이동하실까요?</h2>
<p>나라: {location.country}</p>
<button onClick={() => setIsKorea(!isKorea)}>이동</button>
</div>
);
};
export default MemoComponent;
추가내용
원시(Primitive)타입 (기본형)
Number, String, Boolean, Null, undefined, BigInt
const number =20
const number2 = 20
number === number2
true 나옴
객체(Object)타입 참조형
원시타입을 제외한 모든것
const objnumber = {
number:20
}
const objnumber2 = {
number:20
}
objnumber === objnumber2
false 나옴. 이유는 객체가 만들어진 메모리 주소 번지가 다름
2.useCallback
useMemo는 함수의 결과값을 재사용(결과값을 메모리에 저장) 하고
useCallback은 특수함수(함수자체를 메모리에 저장)를 새로 만들지 않고 재사용한다
구문)
useCallback((num)=>{
return num+1;
}, [deps])
ex)
function Component() {
const calulate = (num) => {
return num + 1
},[item]}
return(
<div>{value}</div>
)
}
useCallback함수를 이용한 실습 1
App.js
import React, { useCallback, useState } from 'react';
import List from './components/List';
const App = () => {
const [number, setNumber] = useState(1);
const [dark, setDark] = useState(false);
const theme={
backgroundColor: dark? "#333" : "#fff",
color: dark? "#fff" : "#333"
}
const getItems = useCallback(() => { //useCallback함수 사용
return [number, number + 1, number + 2] //[1,2,3]
},[number])
// const getItems = useMemo(() => useMemo함수 사용
// (value) => {
// return [number, number + 1, number + 2] //[1,2,3]
// },[number])
return (
<div style={theme}>
<input type="number" value={number}
onChange={e=>setNumber(Number(e.target.value))}
/>
<button onClick={()=>{setDark(!dark)}}>테마변경</button>
<List getItems={getItems}/>
</div>
);
};
export default App;
List.js
import React, { useEffect, useState } from 'react';
const List = ({getItems}) => { //getItems 여기로 받았음 꿀꺽~
const [items, setItems] = useState([]);
useEffect(()=>{
setItems(getItems()) //배열을 리턴해줌[1,2,3]
console.log("숫자가 변동되었습니다.")
},[getItems])
return (
<div>
{items.map((item,index)=><div key={index}>{item}</div>)}
{/* [1,2,3] map으로 돌려줌 map은 새로운 배열로 바꿔줌*/}
{/* <div></div>
<div></div>
<div></div> 이렇게 담김 */}
</div>
);
};
export default List;
useCallback함수를 이용한 실습 2
App.js
import React, { useCallback, useState } from 'react';
import Box from './components/Box';
const App = () => {
const [size, setSize] = useState(100);
const [dark, setDark] = useState(false);
const createBox = useCallback(() => {
return {
backgroundColor: 'pink',
width:`${size}px`,
height: `${size}px`
}
},[size])
const style = {
backgroundColor: dark ? "#333" : "#fff",
color: dark? "#fff" : "#333"
}
return (
<div style={style}>
<input type="number"
value={size} onChange={e=>setSize(e.target.value)}/>
<Box createBox={createBox} />
<button onClick={()=>setDark(!dark)}>변경</button>
</div>
);
};
export default App;
Box.js
import React, { useEffect, useState } from 'react';
const Box = ({createBox}) => {
const [style, setStyle] = useState({});
useEffect(()=>{
console.log("박스키우기")
setStyle(createBox())
},[createBox])
return (
<div style={style}>
</div>
);
};
export default Box;
'react' 카테고리의 다른 글
[React] react Icons 설치, Axios 설치 (0) | 2023.01.16 |
---|---|
[React] Hook 함수정리3(useReducer) (0) | 2023.01.14 |
[React] node-Sass설치 & Styled-component (0) | 2023.01.13 |
[React]Hooks함수 정리1(useState, useRef, useEffect, useContext) (0) | 2023.01.10 |
[React]배열 렌더링하기 실습 (0) | 2023.01.06 |
댓글