자바스크립트 - Next.js

[Next.js] Extra attributes from the server : ... 에러 해결

Lv1_junior_dev 2024. 3. 2. 17:58

Next 14를 사용하는 프로젝트를 하다가 문제에 부딪혔다.

"use client";

import React, { useId } from "react";

import Select from "react-select";

interface OptionData {
  value: string;
  label: string;
}

interface Props {
  area?: boolean;
  status?: boolean;
  options: OptionData[];
}

export default function SelectBox({ area, options }: Props) {
  const placeholder = area ? "지역 선택" : "완료/미완료 여부";
  const id = useId();

  return (
    <Select
      instanceId={id} 
      defaultValue={null}
      isSearchable={true}
      name={area ? "area" : "status"}
      options={options}
      placeholder={placeholder}
    />
  );
}

내가 구현하려는 페이지는 부모는 서버 컴포넌트이고 자식은 클라이언트 컴포넌트이다.

이 때 자식 컴포넌트에서 react-select를 사용하다가 아래와 같은 에러가 떴다.

얜 도대체 무슨 에러인가해서 찾아보니 서버 렌더링하는 컨텐츠와 클라이언트 렌더링하는 컨텐츠가 서로 불일치 할때 나는 에러라고 한다.

 

그래서 찾고 찾다가 해결 방안을 찾았다.

"use client";

import React, { useEffect, useId, useState } from "react";
import { ThemeProvider } from "next-themes";

import Select from "react-select";

interface OptionData {
  value: string;
  label: string;
}

interface Props {
  area?: boolean;
  status?: boolean;
  options: OptionData[];
}

export default function SelectBox({ area, options }: Props) {
  const placeholder = area ? "지역 선택" : "완료/미완료 여부";
  const id = useId();

  const [isMount, setMount] = useState(false);

  useEffect(() => {
    setMount(true);
  }, []);

  if (!isMount) {
    return null;
  }

  return (
    <ThemeProvider attribute="class">
      <Select
        instanceId={id} 
        defaultValue={null}
        isSearchable={true}
        name={area ? "area" : "status"}
        options={options}
        placeholder={placeholder}
      />
    </ThemeProvider>
  );
}


Providers 컴포넌트에 현재 마운트 상태를 확인하는 상태 isMount를 false로 초기화하고 isMount가 false 일 때는 null을 리턴하고, true 일 때는 ThemeProvider를 리턴하도록 작성하면 해당 에러가 사라지는 것을 확인할 수 있다.

 

대신 자식 컴포넌트가 한박자 느리게 렌더링 되어서 조금 거슬리긴 하는데 

이 부분은 Suspense를 쓰거나 다른 좋은 해결방안을 찾아보도록 해야겠다.

 

참고 : https://www.npmjs.com/package/next-themes

 

next-themes

An abstraction for themes in your Next.js app.. Latest version: 0.2.1, last published: a year ago. Start using next-themes in your project by running `npm i next-themes`. There are 309 other projects in the npm registry using next-themes.

www.npmjs.com