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.js' 카테고리의 다른 글
[Next.js] Next.js 14에서 react-select를 사용해보자 (feat. 트러블 슈팅) (0) | 2024.03.04 |
---|---|
[Next.js] useSelectedLayoutSegment와 useSelectedLayoutSegments에 대해 알아보자 ! (0) | 2024.02.22 |
[Next.js] Next.js의 기본적인 정보에 대해서 알아보자 (0) | 2024.02.21 |