[React.js] PureComponent

2021. 11. 10. 23:44카테고리 없음

# Pure하다?

“Pure하다” 요 개념이 재미있다고 생각한 게 이 내용을 정리하게 된 계기인데요.

 

React 개발을 하다가 아래와 같은 패턴을 마주하게 된 적이 있으신가요?

 

const Component = ()=>{
  const [stateValue, setStateValue] = useState<number>(0);

  const func1 = (value: number)=>{
    return value + 1;
  }

  const func2 = ()=>{
    return stateValue + 1;
  }

  return 
    <div>
      <label>{func1(stateValue)}</label>
      <label>{func2()}</label>
    </div>
}

 

두 개의 함수는 같은 일을 하지만 (물론 호출부는 다르겠죠! func1은 param이 있으니까요) 한 가지 차이점이 있습니다. func1은 출력 결과가 입력 param 에만 영향을 받지만, func2는 외부의 값 stateValue에 영향을 받습니다. 즉, func1은 Pure하고 func2는 Impure 합니다.

 

🧐 무엇이 더 나은 패턴일까요? 
😎 Side effect가 없기 때문에 직관적이고 유지보수하기 쉬운 Pure Function이 더 나은 패턴입니다. 위 코드만 봐도, setStateValue가 어디서 호출될 지 알 수 없기 때문에 func2 return Value의 일관성을 보장할 수 없습니다. 또 재사용성 측면에서도 Pure Function이 좀 더 낫겠네요. 

 

+) 정리하면서 추가로 생각이 났는데, React 성능 개선을 위해 UseRef, React.memo 등을 적용하기에도 Pure Function만 있는 게 더좋았습니다. Pure Function인 경우 Side Effect에 대한 고민 없이 함수 object 자체를 메모이제이션하기 편했기 때문입니다.

 

# React Component vs PureComponent


처음에 React의 PureComponent가 Pure Function의 개념이 동일하게 적용된 Component인 줄 알고, Props가 상수로만 되어있는 건가… 머지… 혼자 추측했었는데요 ㅋㅋㅋ 조금 다른 개념이더라구요. React 공식 페이지에 아래와 같이 친절히 설명되어 있습니다.

React.Component는 setState가 일어나면 재렌더링 되는 반면, React.PureComponent는 얕은 비교를 통해 값이 변경되었을 때만 재렌더를 일으킵니다. 

 

개인적으로는 부모 컴포넌트 하위에 단순한 자식 컴포넌트 다수가 있는 경우 쓰기 좋았던 것같아요.

예를 들면 게시판의 공지사항이 있을 것 같습니다. 공지사항 페이지(부모)의 state가 아무리 변경 되더라도 공지사항 항목(자식)은 한 번 불려온 이후로 재 렌더 될 필요가 거의 없을테니까요. 공지사항 항목이 갖고있어야 하는 state는 boolean 타입의 showDetail 정도일 것 같아요. 그러면 얕은 비교로 인해 착오가 발생할 일이 없으니, PureComponent를 써도 되겠네요!

# 그럼 PureComponent가 좋은 것 아닌가요?

Component 내에 얕은 비교로는 변화를 감지 할 수 없는 복잡한 자료구조가 포함되어있다면, 예상과 다르게 동작할 수 있으므로 주의해야합니다. React 성능 개선은 다 이런 느낌이 것 같아요. 잘 모르고 쓰면 오히려 버그가 되어버리니까요! (그런데 이건 다른 언어나 프레임워크도 마찬가지겠네요 ㅎㅎ)
+) 정리하면서 추가로 또 생각이 났는데...! 주소값이 동일한 두 객체는 얕은 비교에서 같다고 판단되어 버리는게 문제라면 lodash로 대체하면 문제가 없을까요? 이건 확인해봐야겠어요.