React 메모이제이션
App이라는 컴포넌트가 있으면 아래 child1,2,3,4, 의 하위 컴포넌트가 존재 한다
App컴포넌트가 랜더링 되면 아래의 하위 컴포넌트도 모두다 랜더링 되게에 메모리를 많이 소비하게 된다 이러한 문제점을 해결하기 위해 memo,useCallback,useMemo를 사용하여 상위 컴포넌트가 랜더링 되어도
랜더링 하게 하는걸 막을수 있다
폴더 구조
App코드
import { Child1 } from './components/Child1.jsx';
import { Child4 } from './components/Child4.jsx';
export const App = memo(() => {
console.log("APP 랜더링")
const [num, setNum] = useState(0);
const onClickButton = () => {
setNum(num + 1);
};
return (
<>
<button onClick={onClickButton}>버튼</button>
<p>{num}</p>
<Child1 />
<Child4 />
</>
);
});
각 부분 마다 현재 랜더링 하고있는지 에대한 콘솔 값을 기입하였다,
그렇기에 app가 랜더링 되면 그 아래에 포함된 모든 컴포넌트들은 랜더링 되어야한다
app에 있는 버튼을 누를때 마다 랜더링 되게이 그 아래 있는 모든 컴포넌트들도 랜더링 된다
이걸 막기 위해 memo를 이용한다
child1에만 memon를 적용해보면
export const Child1 = memo((props) => {} ))
app 의 버튼을 클릭하면
app 자기 자신과 child4만 랜더링 된다
함수에 대해서 메모이제이션 useCallback
import { Child1 } from './components/Child1.jsx';
import { Child4 } from './components/Child4.jsx';
export const App = memo(() => {
console.log("APP 랜더링")
const [num, setNum] = useState(0);
const onClickButton = () => {
setNum(num + 1);
};
const onClickReset = () => {
setNum(0);
};
return (
<>
<button onClick={onClickButton}>버튼</button>
<p>{num}</p>
<Child1 onClickReset={onClickReset} />
<Child4 />
</>
);
});
child1에서 app 의 값을 초기화 하기위해 onclickReset라는 함수를 만들었다
child1의 코드는
import "./Child.css";
import { useState,memo,useMemo } from 'react';
import {Child2} from './Child2.jsx';
import {Child3} from './Child3.jsx';
const style2 ={
backgroundColor : "Lightblue",
}
export const Child1 = memo((props) => {
console.log("Child1 랜더링")
//props로 부터 받음 함수 전개
const {onClickReset} = props;
return (<>
<div className="child1" style={style2}>
<button onClick={onClickReset}>리셋</button>
<p>child1 <button >child2버튼</button>
<Child2 />
<Child3}/>
</div>
</>)
})
이렇게 app의 함수를 받아오게 된다면 app버튼 클릭시
memo를 사용하였더라도 child1도 랜더링 된다 이때 이걸 막기 위해 usecallback 을 사용한다
app 부분에서
const onClickReset =useCallback ( () => {
setNum(0);
},[]);
이렇게 수정해주면 child1이 app로 부터 함수를 받아도 랜더링이 되지 않는다
변수에 대해서 메모이제이션 useMemo
이번에는 child1에서 시작할거면 child2,3는 memo 되어있는 상태이다
child1의 코드는
export const Child1 = memo((props) => {
console.log("Child1 랜더링")
const [num2,setNum]=useState(0);
const [num3,setNum3]=useState(0);
//props로 부터 받음 함수 전개
const {onClickReset} = props;
const onClickButton = ()=>{
setNum(num2+1)
}
const memoizedNum2 = useMemo(() => num2, []);
const onClickButton2 = ()=>{
setNum3(num3+1)
}
return (<>
<div className="child1" style={style2}>
<button onClick={onClickReset}>리셋</button>
<p>child1 <button onClick={onClickButton}>child3버튼</button>
<span>{num2}</span></p>
<p><button onClick={onClickButton2}>child2버튼</button>
<span>{num3}</span> </p>
<Child2 year={num3}/>
<Child3 year={memoizedNum2}/>
</div>
</>)
})
num3라는 변수는 child2에 그냥 상속하고
num2는 memoizedNum2라는 함수에 의해 메모라이제이션을 거쳐서 child3로 넘어간다
이때 child3버튼을 누르면 child1만 랜더링 된다
child2버튼을 누르면 child1과 child2 모두다 랜더링이 된다.
이걸 이용하면 불필요한 랜더링을 줄일수 있으면 자기가 원하는 함수 변수에 대해서만 랜더링을 진행할수 있다
'html,css,js 공부 > React' 카테고리의 다른 글
리액트 props 사용법 (1) | 2024.11.23 |
---|---|
리액트 Global State (0) | 2024.03.23 |
React css 적용방법 (0) | 2024.03.19 |
리액트 2일(속성 이용법,외부 컴포넌트 사용,useState,상속 ) (1) | 2024.03.19 |
리액트 공부1일차 (0) | 2024.03.17 |