몰라서 잠깐 널 미워했어 next.js야 미안해
이 오류는 핫모듈교체 (HMR, hot module replacement) 그러니까 우리가 핫리로딩이라고 부르는 게 발생할때 Recoil atom이 중복 생성되어서 발생한 것이었다.
전역 객체를 사용해서 모듈을 저장한다. 이 경우에는 Recoil atom이 될 것이다. 그리고 다시 사용할 수 있도록 관리한다. 이게 캐싱이랑 비슷하다고 생각했다.
즉 새로 로드되거나 재 실행될 때마다 새로운 상태를 생성하는 것 대신에 이미 생성된 것을 재사용하자. 라고 해서 중복 문제를 해결하자는 것이다.
그럼 어떻게 했는지 보자.
import { atom } from "recoil";
if (!global._recoilAtoms) {
global._recoilAtoms = {};
}
export const modalState =
global._recoilAtoms.modalState ||
atom({
key: "modalState",
default: false,
});
global._recoilAtoms.modalState = modalState;
global._recoilAtoms
객체를 초기화 한다.global
객체는 node.js 환경에서 전역 범위를 나타내며 클라이언트 사이드에서는 window 객체가 global 객체이다. 근데 왜 window 안썼냐면 next.js는 서버사이드인데 window객체는 클라이언트 사이드에 존재한다. 그러니까 브라우저 환경에서만 존재하기 때문에 window를 서버사이드에서 쓰려고 하면 에러가 발생할 수 있다. 그래서 next.js에서는 global을 사용한다고 한다. 이것은 서버와 클라이언트 양쪽에서 안전하게 동작하고 Node.js에서도 전역객체로 작동하고 클라이언트사이드에서도 전역객체로 동일하게 작동한다. 그러면 일관되게 전역 상태를 관리할 수 있다.
atom 체크 및 생성
modalState라는 키를 가진 이름의 atom 때문에 이 문제가 발생했다.
그래서 이걸 생성하기 전에 global._recoilAtoms
에 이게 있는지 확인한다. 만약에 없으면 새로 생성한다.
Atom 저장
modalSState atom을 global._recoilAtom
에 저장하여 다음에 이 모듈이 다시 로드될 때 중복 생성을 방지한다.
인터넷에서 찾아본 것들을 보면
1. key 중복검사를 비활성화 한다