무작정 프로젝트 해보기 - 6 (전역 변수 상태관리, zustand 리렌더링 최적화 하기)

오늘처음해요·2024년 2월 23일
0
post-thumbnail

오늘의 작업물

zustand 써보기

요즘 프론트엔드 상태관리 툴을 보면

Redux, mobX, recoil, react-query 등 많은데

가장 많이 보이는 조합으로는 react-query(서버), recoil 혹은 zustand 인것 같다

프론트엔드 상태관리 실전 편 with React Query & Zustand #우아콘2023 #우아한형제들

를 보고 나서 한번 Zustand도 써보고 recoil도 써봐야겠다 생각하고 있었는데

zustand가 recoil 같은 다른 상태관리 툴보다 6~20배 정도 용량이 작다고 해서

앱에는 엄청 유리하지 않을까 싶어서 채택했다 (사용법이 쉬운 것은 덤)

// src/stores/MenuOrderData.js

import { create } from 'zustand';

const useMenuOrderStore = create((set) => ({
  id: 0,
  increaseId: () => set((prev) => ({ id: prev.id + 1 })),
}));

이런 식으로 전역적으로 꺼내 써야되는 요소를 선언하고,
해당 값을 수정할 함수까지 같이 선언해준다 (여러 컴포넌트에서 선언해서 쓴다면 오류가 발생할 가능성이 매우 농후함)

zustand의 set은 useState()의 setState처럼 기존 값을 파라미터로 가진다

따라서 prev.id와 같이 쓰면 기존 id를 받을 수 있고
리턴 값이 새로운 id값이 된다


// MenuOption.js
import useMenuOrderStore from '../../stores/MenuOrderData';

const MenuOption = ({ id, price, amount }) => {
  const { id } = useMenuOrderStore();
}

이런 식으로 useMenuOrderStore을 불러와서 그냥 구조분해로 사용하면 된다

명심해야 할 부분은 useState처럼 값을 그대로 수정하지 말고
반드시 increaseId와 같이 set을 이용한 함수를 선언해두고 변경해야 한다.

const useMenuOrderStore = create((set) => ({
  ...
  setId: (val) => set({id: val})
}));

최적화

최적화가 개판이다

[장바구니] 페이지에서 [헤더], [더 담으러 가기] / [메뉴] 페이지의 [메뉴 리스트]

리렌더링 되지 않게 해야겠다

처음에는 [장바구니] 페이지의 요소들이 count 올라갈 때 React.memo로 최적화 해야되나 싶었는데 찾아보니까 엄청 자주 반복되는, 동일한 프롭을 받는 컴포넌트가 아니면 오히려 메모리만 잡아먹어서 성능이 느려질 수 있다고 하니

아티클에서 권장한 성능 문제가 발생하기 전에는 React.memo는 자제하라 를 따라야겠다


zustand에 저장된 함수 참조하는 컴포넌트 최적화 하기

여기 MenuOrderData에 저장된 deleteMenu()를 참조하는
컴포넌트가 있습니다

이 컴포넌트는 한번 생성되면 바뀔 일이 없는 컴포넌트 입니다
적용 전

amount state만 변경됨에도 부모 컴포넌트가 재렌더링되면서
같이 랜더링 되는 것을 확인할 수 있습니다

useCallback, React.memo로도 재렌더링을 막을 수 없어서 고민했는데

zustand 선택적 참조로 해결했습니다

적용 후

물론 이걸로 인해서 실제로 성능이 좋아졌는지
오히려 메모리만 많이 잡아먹어서 성능적으로 손해보는 것은 아닌지

걱정이 되긴하지만 어쨋든 지금 목표는 최적화 할 수 있는 방법을 공부하는 것이기에

나중에 현직에 계신 개발자 분들에게 이게 좋은 접근법인지 여쭤보는 걸로 하고 넘어가겠습니다

RN 성능 체크할 수 있는 도구를 찾아 봐야겠네요

0개의 댓글