import React, { useState } from "react";
import "./styles.css";
export default function App() {
const [count, setCount] = useState(1);
return (
<div className="App">
<p>Value of count is {count}</p>
<Child />
</div>
);
}
function Child() {
console.log("Child is getting rendered");
return <h1>I am a child</h1>;
}
우리가 예상할 수 있는 아주 기본적인 예시로 Child Component는 1번 렌더 된다. 만약 위의 경우에 count+1 할 수 있는 버튼을 만들어 클릭한다면 어떨까?
import React, { useState } from "react";
import "./styles.css";
export default function App() {
const [count, setCount] = useState(1);
return (
<div className="App">
<p>Value of count is {count}</p>
<Child />
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
function Child() {
console.log("Child is getting rendered");
return <h1>I am a child</h1>;
}
이 경우에는, 클릭할 때 마다 child component는 diff algorithm에 따라 리랜더된다. 만약 리랜더 시키고 싶지 않다면, memo를 사용할 수 있습니다.
function Child() {
console.log("Child is getting rendered");
return <h1>I am a child</h1>;
}
const MyChild = React.memo(Child);
이제 MyChild를 사용한다면 리랜더를 막을 수 있지만, Child Component에 prop이 전달된다면 이야기가 다르다. 예를 들어
export default function App() {
const [count, setCount] = useState(1);
const callback = () => {}
return (
<div className="App">
<p>Value of count is {count}</p>
<MyChild callback={callback} />
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
이 경우엔 버튼을 클릭하면 모든 상태가 변화함에 따라 모든 함수들이 재생성 되기 때문에 memo를 감쌌지만 여전히 리랜더가 발생한다. 이런 경우를 방지하기 위해 const callback = useCallback(() => {}, []); 와 같이 useCallback을 사용할 수 있고 memozation이 되었기 때문에 리랜더를 방지할 수 있습니다.
하지만 만약 inline function을 사용했다면 어떨까? <MyChild callback={() => callback()} /> 사실 똑같이 useCallback으로 감싸져 있지만, 위와 같이 제공한다면 callback 함수는 메모상태 임에도 메모 상태가 아닌 익명 함수를 child component에게 제공하게 되어 앞서 말한 퍼포먼스적 장점을 갖지 못하게 됩니다.
https://ishwar-rimal.medium.com/stop-passing-inline-functions-as-a-prop-in-react-cf39efc60b82