[next.js] Duplicate Atom key 문제

냐옹·2023년 11월 16일
0

Next

목록 보기
4/4

몰라서 잠깐 널 미워했어 next.js야 미안해

문제

Expectation Violation : Duplate atom key 오류

  • 지금 Next.js를 사용하여 프로젝트를 하고 있는데 뭔가 이상했다.
  • 핫리로딩을 하는데 스타일 조금 바꾼 것 뿐인데 엄청 오래 걸렸다.
    - 한 10초?

왜 일어났는가?

이 오류는 핫모듈교체 (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;
  1. 전역 객체를 초기화 한다.
    global._recoilAtoms객체를 초기화 한다.
    이 객체는 Recoil atom들을 저장하는데 사용된다.
    global 객체는 node.js 환경에서 전역 범위를 나타내며 클라이언트 사이드에서는 window 객체가 global 객체이다.

근데 왜 window 안썼냐면 next.js는 서버사이드인데 window객체는 클라이언트 사이드에 존재한다. 그러니까 브라우저 환경에서만 존재하기 때문에 window를 서버사이드에서 쓰려고 하면 에러가 발생할 수 있다. 그래서 next.js에서는 global을 사용한다고 한다. 이것은 서버와 클라이언트 양쪽에서 안전하게 동작하고 Node.js에서도 전역객체로 작동하고 클라이언트사이드에서도 전역객체로 동일하게 작동한다. 그러면 일관되게 전역 상태를 관리할 수 있다.

  1. atom 체크 및 생성
    modalState라는 키를 가진 이름의 atom 때문에 이 문제가 발생했다.
    그래서 이걸 생성하기 전에 global._recoilAtoms에 이게 있는지 확인한다. 만약에 없으면 새로 생성한다.

  2. Atom 저장
    modalSState atom을 global._recoilAtom에 저장하여 다음에 이 모듈이 다시 로드될 때 중복 생성을 방지한다.

다른방법은 없을까?

인터넷에서 찾아본 것들을 보면
1. key 중복검사를 비활성화 한다

  • 이건 해결책이 될 수 없다고 본다.
  • 아플때 해결책이 그쪽의 신경을 차단하면 된다 라고 하기에는..
    - 근데 신경치료 생각하면 또 그렇긴하네 어쨋든..
    ~

0개의 댓글