-
React의 자식 컴포넌트 재렌더링 방지하는 법. shouldComponentUpdate 함수 사용.문제 해결 기록 2022. 9. 3. 01:23
프로젝트를 수행하면서 부모 컴포넌트의 state가 변경되어도 재렌더링이 되지않았으면하는 자식 컴포넌트가 있었습니다.
특히 해당 자식 컴포넌트에 재렌더링이 부담스러운 복잡한 로직이 있으며,
변경된 부모 컴포넌트의 state가 해당 자식 컴포넌트의 jsx에 반영되지않는 경우가 특히 그럴것입니다.
구글링을 해 본 결과 예전 리액트버전에서 제공하는 class 컴포넌트 안에 shouldComponentUpdate 함수를 선언하여,
그 함수가 반환하는 boolean값으로 자식 컴포넌트의 업데이트 여부를 설정할 수 있음을 파악했습니다.
React.Component – React (reactjs.org)
위의 공식문서 링크에서 설명하는 shouldComponentUpdate 함수의 예시입니다.
import React, { Component } from "react"; class Counter2 extends Component { shouldComponentUpdate (nextProps, nextState) { // Rendering the component only if // passed props value is changed if (nextProps.value !== this.props.value) { return true; } else { return false; } } render() { console.log("Counter 2 is calling"); return ( <div> <h2>Counter 2:</h2> <h3>{this.props.value}</h3> <button onClick={this.props.onClick}>Add</button> </div> ); } } export default Counter2;
class 컴포넌트 안의 shouldComponentUpdate 함수는 해당 컴포넌트가 재렌더링되기 직전에 실행됩니다.
중요한 점은 이 함수는 첫 인자로 컴포넌트가 재렌더링된다면 갖게 될 props들의 상태를 미리 입력받으며,
두 번째 인자로는 미래의 state를 인자로 입력받습니다.
위의 코드에는 nextProps와 nextState로 인자를 받고있음을 볼 수 있습니다.
따라서 nextProps객체가 가진 속성의 값과 현재 props객체의 속성값을 비교하거나 또는, 같은 방식으로 현재의 state와 재렌더링 후 미래의 state값과 비교연산 등의 비즈니스 로직을 수행하고, 그 반환값에 따라서 재렌더링 실행 여부를 설정할 수 있습니다.
만약 반환값이 false라면 컴포넌트는 재렌더링을 건너뛰고, true라면 재렌더링을 실행할것입니다. (물론 default값은 true입니다.)
주의해야할 점은 만약 shouldComponentUpdate 함수 안에서 수행하는 비즈니스 로직이 지나치게 복잡하다면 성능을 저하시킬것입니다.
그리고 지금 함수형 컴포넌트를 사용하는 react 버전에서는 다른 방식으로 사용합니다.
const ProjectComponent = (props) => { const { count } = props } const judgeEqual = (prevProps , nextProps) => { return prevProps.count === nextProps.count } export default React.memo(ProjectComponent , judgeEqual)
전반적인 흐름은 같지만 컴포넌트를 export할 때 React Memo함수의 두 번째 인자에 이전의 props와 미래의 props로 비즈니스 로직을 수행해 boolean값을 반환하는 함수를 정의해 넣어줍니다.
class 컴포넌트의 shouldComponentUpdate함수와의 차이가 있다면, 이 함수는 첫 번째 인자로 이전의 props객체, 두 번째로 재렌더링 된 후 미래의 props객체를 인자로 받습니다.
또다른 중요한 차이점으로는 위의 judeEqual함수는 true를 반환하면 재렌더링되지 않는다는 것입니다.
즉, shouldComponentUpdate과 반대라는 것을 기억할 필요가 있습니다.
'문제 해결 기록' 카테고리의 다른 글
A non-serializable value was detected in the state 에러 해결. (0) 2022.10.24 useCallBack hook과 setState 실행 문제. (0) 2022.09.08 StompJs에서 이미지 이진 데이터 전송하기, 문제 해결 (0) 2022.09.06 Cannot find module './*.module.css' or its corresponding type declarations. 에러 핸들링 (0) 2022.09.01