리액트에서 부모컴퍼넌트가 리렌더링 되면 자신도 리렌더링된다.React.memo를 사용하면 이를 방지 할 수 있다.
import React, { useState,useEffect} from "react";
type props = {text:string};
type myProps = {count:number};
const TextView = React.memo(({text}:props)=>{
useEffect(()=>{
console.log(`update:${text}`);
});
return<div>{text}</div>
});
const CountView = React.memo(({count}:myProps)=>{
useEffect(()=>{
console.log(`update:${count}`);
});
return(
<div>
{count}
</div>
);
});
const OptimizeTest = ()=>{
const [count,setCount] = useState<number>(0);
const [text ,setText] = useState<string>('');
return(
<div style={{padding:50}}>
<div>
<h2>Count</h2>
<CountView count={count}/>
<button onClick={()=>setCount(count+1)}>+</button>
</div>
<div>
<h2>Text</h2>
<TextView text={text}/>
<input value={text} onChange={(e)=>setText(e.target.value)}/>
</div>
</div>
)
}
export default OptimizeTest;
객체와 배열은 비교시 얕은 비교(주소)를 한다.따라서 areEqual 메소드를 활용을 하여 동일한 값인지 아닌지를 확인 해야 한다.
다음은 예시코드이다.
let obj1 = { a: 1, b: { c: 2 } };
let obj2 = { a: 1, b: { c: 2 } };
if (obj1.b.c === obj2.b.c) {
console.log(`똑같다`);
}
if (obj1.b !== obj2.b) {
console.log(`다르다`);
}
const areEual = (prevProps:props, nextProps:props)=>{
if(prevProps.obj.count === nextProps.obj.count){
return true;
}
return false;
}
import React, { useState,useEffect} from "react";
interface props {
obj:myProps
}
type myProps = {count:number};
const CounterA = React.memo(({count}:myProps)=>{
useEffect(()=>{
console.log(`countA:${count}`);
})
return(
<div>
{count}
</div>
)
});
const CounterB = ({obj}:props)=>{
useEffect(()=>{
console.log(`countB:${obj.count}`);
})
return(
<div>
{obj.count}
</div>
)
}
const areEqual = (prevProps:props, nextProps:props)=>{
if(prevProps.obj.count === nextProps.obj.count){
return true;
}
return false;
}
const MemoizedCounterB = React.memo(CounterB,areEual);
const OptimizeTest = ()=>{
const [count ,setCount] = useState(0);
const [obj,setObj] = useState({
count:1
});
return(
<div style={{padding:50}}>
<div>
<h2>Counter A</h2>
<CounterA count={count}/>
<button onClick={()=>setCount(count)}>A 버튼</button>
</div>
<div>
<h2>Counter B</h2>
<MemoizedCounterB obj={obj}/>
<button onClick={()=>setObj({count:obj.count})}>B 버튼</button>
</div>
</div>
)
}
export default OptimizeTest;