요즘 프론트엔드 상태관리 툴을 보면
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는 자제하라
를 따라야겠다
여기 MenuOrderData
에 저장된 deleteMenu()
를 참조하는
컴포넌트가 있습니다
이 컴포넌트는 한번 생성되면 바뀔 일이 없는 컴포넌트 입니다
적용 전
amount
state만 변경됨에도 부모 컴포넌트가 재렌더링되면서
같이 랜더링 되는 것을 확인할 수 있습니다
useCallback, React.memo
로도 재렌더링을 막을 수 없어서 고민했는데
zustand 선택적 참조
로 해결했습니다
적용 후
물론 이걸로 인해서 실제로 성능이 좋아졌는지
오히려 메모리만 많이 잡아먹어서 성능적으로 손해보는 것은 아닌지
걱정이 되긴하지만 어쨋든 지금 목표는 최적화 할 수 있는 방법을 공부하는 것이기에
나중에 현직에 계신 개발자 분들에게 이게 좋은 접근법인지 여쭤보는 걸로 하고 넘어가겠습니다
RN 성능 체크할 수 있는 도구를 찾아 봐야겠네요