banner
  1. About
  2. Blog
  3. Contact
프로그래밍 · 

[Zustand] The result of getSnapshot should be cached to avoid an infinite loop 에러 해결하는 법


화면 캡처 2025-03-11 101643.png

내용을 보면 이러한데 아래와 같이 Maximum update depth exceeded 에러와 함께 뜹니다.


화면 캡처 2025-03-11 101632.png

아래와 같은 단순한 코드가 에러를 발생시키는데요.


const values = useStore((state) => [1, 2, 3])


에러가 발생하는 원인은 useStore 함수가 작동하는 방식에 있습니다.


useStore는 파라미터로 받은 함수를 이용해 values처럼 결과로 뽑아냅니다. 그리고 values는 변경될 때마다 컴포넌트를 다시 렌더링합니다. 이때 컴포넌트를 다시 렌더링하면서 useStore는 다시 파라미터로 받은 함수를 이용해 새로운 결과를 뽑아냅니다. 만약 새로 뽑아낸 결과가 기존 결과랑 다르다면 리턴값 values를 새로 업데이트합니다. 그러면 컴포넌트가 또 다시 렌더링되겠죠. 이렇게 무한 반복입니다.


반복을 피하는 방법은 새로운 결과를 기존 결과와 일치시키는 겁니다. 언뜻 보기에 [1, 2, 3] 배열은 기존 결과와 똑같을 거라고 예상할 수 있지만, 실제로는 다릅니다. 배열은 원시 값이 아니기 때문에 비교했을 때 서로를 같은 객체가 아니라고 판별합니다. 아래 코드가 무한 반복을 일으키지 않는 것과는 다르게 말입니다.


const value = useStore((state) => 1);


여기서 1은 원시값이기 때문에 그렇습니다. 쉽게 말해서 1 === 1이지만, [] !== []인 것이죠.


하지만 매번 원시값을 사용할 수는 없기 때문에 배열 같은 참조 객체를 결과로 사용하는 방법은 바로 Zustand가 지원하는 useShallow 함수를 사용하는 것입니다.


import useShallow from "zustand/shallow";

const values = useStore(useShallow((state) => [1, 2, 3]));


문법이 길어졌지만 어쩔 수 없네요. 아무튼 useShallowuseMemouseCallback이 해주는 역할을 동일하게 해줍니다.

댓글 0

프로그래밍 카테고리 다른 글