프론트엔드/Java Script
JavaScript Sec05_8 최적화 2 - 컴포넌트 재사용
영초_
2024. 2. 24. 23:49
React.memo
함수형 컴포넌트에게 업데이트 조건을 걸자
- 이 경우 부모 컴포넌트가 리렌더 되기 때문에 자식 컴포넌트들이 리렌더 된다. 하지만 count 상태만 변화했기 때문에 TextView는 리렌더 될 필요가 없다.
- 이렇게 업데이트 조건을 걸어 불필요한 컴포넌트 재사용을 막는다.
React.memo
- React.memo는 고차 컴포넌트이다.
- 고차 컴포넌트 : 파라미터로 컴포넌트를 가져와 새 컴포넌트를 반환하는 함수
- 재사용이 필요한 함수를 React.memo로 감싸준다.
- 이렇게 React.memo로 감싸면 prop으로 전달된 text가 변하지 않으면 리렌더링을 하지 않게 된다.
const MyComponent = React.memo(function MyComponent(props) {
/* props를 사용하여 렌더링 */
});
- 컴포넌트가 동일한 prop을 받아 동일한 결과를 렌더링해낸다면, React.memo를 호출하고 결과를 memorizing 하도록 래핑한다.
- 즉 React는 컴포넌트를 렌더링하지 않고 마지막으로 렌더링된 결과를 재사용한다.
참고 코드)
import React, { useEffect, useState } from 'react';
const Textview = React.memo(({ text }) => {
useEffect(() => {
console.log(`Update :: Text : ${text}`);
});
return <div>{text}</div>;
});
const Countview = React.memo(({ count }) => {
useEffect(() => {
console.log(`Update :: Count : ${count}`);
});
return <div>{count}</div>;
});
const OptimizeTest = () => {
const [count, setCount] = useState(1);
const [text, setText] = useState('');
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;
# Q & A
- CounterA에서는 A Button을 눌러도 값 자체가 바뀌지 않았으므로 React.memo에 의해 리렌더가 되지 않았는데
- CounterB에서는 B Button을 눌렀을 때 값이 바뀌지 않는데도 리렌더가 되었다.
- 자바스크립트에서는 객체를 비교할 때 객체의 주소를 비교하는 얕은 비교를 한다
- 객체를 깊이 비교하려면 areEqual 함수를 새로 만들어 활용한다
- 객체의 프로퍼티를 비교하여 같으면 true, 다르면 false를 리턴하는 함수 areEqual을 만들고 React.memo함수의 첫 번째 인자에 재사용 할 컴포넌트, 두 번째 인자에 areEqual 비교함수를 넣어 areEqual이 true면 컴포넌트가 리렌더 되지 않고 false면 리렌더 되도록 한다.