요소의 불필요한 렌더링 반응
방금 React를 배우기 시작했고 quotes API를 호출하는 작은 앱을 모았습니다. API에는 임의의 따옴표를 반환하는 엔드 포인트가 있습니다. 앱이 처음로드되면 API를 호출하고 견적을 표시하며 클릭하여 새로운 임의 견적 (API에 대한 새로운 호출)을 얻을 수있는 버튼이 있습니다.
App이라는 루트 구성 요소가 있습니다. 이 구성 요소에는 QuoteWrap 구성 요소가 자식으로 있습니다. QuoteWrap 구성 요소에는 두 개의 하위 항목이 있습니다. 새 무작위 견적을 가져 오는 데 사용되는 버튼과 견적 작성자와 견적 자체를 표시하는 Quote 구성 요소입니다. 다음은 QuoteWrap 구성 요소 내부의 코드입니다.
export default function QuoteWrap() {
const { quoteData, isLoading, fireNewCall } = useQuote();
const handleClick = () => {
fireNewCall();
};
return(
<>
<button onClick={handleClick}>Get random quote</button>
{ isLoading ?
<h2>Loading...</h2>
:
<Quote author={quoteData.author} quote={quoteData.quote} />
}
</>
);
}
useQuote ()는 API 호출을 관리하고 3 개의 값을 반환하는 사용자 지정 후크입니다. 1- 데이터, 2- 호출이 진행중인 경우, 3- API를 호출하는 함수입니다.
분명히 버튼을 클릭 할 때마다 전체 QuoteWrap 구성 요소가 다시 렌더링됩니다 (quoteData 및 isLoading 변경). 그러나 실제로 버튼은 변경되지 않으므로 다시 렌더링 할 필요가 없습니다.
그래서 저는 생각했습니다 : 좋아요, 버튼을 앱 컴포넌트로 옮길 수 있습니다. 하지만 useQuote 후크에서 fireNewCall 함수에 액세스 할 수 없습니다.
버튼이 다시 렌더링되지 않도록하려면 어떻게해야합니까? 이 경우에도 중요합니까? 아니면 React 리 렌더에 너무 집착하고 있습니까?
감사!
답변
구성 요소는 QuoteWrap이 렌더링 될 때마다 handleClick 함수가 변경 될 때마다 다시 렌더링됩니다.
해결책은 useCallback 후크입니다. useCallback은 종속성이 변경되지 않은 한 QuoteWrap이 렌더링 될 때마다 handleClick에 동일한 함수를 반환합니다.
https://reactjs.org/docs/hooks-reference.html#usecallback
다음과 같이 사용합니다.
const handleClick = useCallback(() => {
fireNewCall();
},[fireNewCall]);
fireNewCall은 종속성이므로 useQuote가 안정적인 fireNewCall 함수를 반환하는 한 handleClick 속성이 변경되지 않았으므로 버튼이 다시 렌더링되지 않습니다.
React re-renders에 너무 집착 할 수 있다고 생각합니다. handleClick경우에 따라 변경 될 때 fireNewCall변경 되어야 하므로 버튼을 다시 렌더링 해야합니다 . 비록 handleClick변경되지 않을 것입니다. 요소 다시 렌더링에 대해 생각할 필요가 없습니다.
Benjamin과 Viet가 말한 것과 거의 비슷합니다. 원래 코드에서는 각 렌더링에서 handleClick에 새 함수가 할당됩니다. 를 사용 React.useCallback하여 원래 함수 참조를 유지하고 종속성 배열의 내용이 변경 될 때만 업데이트 할 수 있습니다 .이 경우 fireNewCall종속성 배열로 이동하면됩니다.
그러나 Viet이 말했듯이 그것에 너무 집착하지 마십시오. 사용하면 React.useCallback코드가 느려질 수도 있습니다. 자세한 내용은 Kent C. Dodds When to useMemo 및 useCallback 게시물을 참조하십시오.