inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

Next + React Query로 SNS 서비스 만들기

안녕하세요 아직 수강중이긴한데 실무에서 작업중 궁금한게 있어서 질문드립니다!

해결된 질문

1816

밍끼

작성한 질문수 9

0

안녕하세요, 강의는 수강중이기도하고 아래에 비슷한 맥락의 질문이 있는데 제가 이해한게 맞나 궁금해서
질문 올립니다!

현재 next14 버전과 styled-component를 사용중이며 공식문서
https://nextjs.org/docs/app/building-your-application/styling/css-in-js#styled-components
내용 과 검색등을 통하여 적용하였습니다.

// libs/styledCompnents/Registry.tsx

'use client';

import { useServerInsertedHTML } from 'next/navigation';
import { ReactNode, useState } from 'react';
import { ServerStyleSheet, StyleSheetManager } from 'styled-components';

const Registry = ({ children }: { children: ReactNode }) => {
  const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet());

  useServerInsertedHTML(() => {
    const styles = styledComponentsStyleSheet.getStyleElement();
    styledComponentsStyleSheet.instance.clearTag();
    return <>{styles}</>;
  });

  if (typeof document !== 'undefined') {
    return <>{children}</>;
  }

  return (
    <StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
      {children}
    </StyleSheetManager>
  );
};

export default Registry;
//libs/styledComponets/Provider.tsx

'use client';

import { ThemeProvider } from 'styled-components';
import GlobalStyles from '@/styles/GlobalStyles';
import theme from '@/styles/theme';
import { PropsWithRequiredChildren } from '@/types/common';
import { StyledComponentsRegistry } from '.';

const Providers = (props: PropsWithRequiredChildren) => {
  return (
    <StyledComponentsRegistry>
      <ThemeProvider theme={theme}>
        <GlobalStyles />
        {props.children}
      </ThemeProvider>
    </StyledComponentsRegistry>
  );
};

export default Providers;

 

// layout.tsx

import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import AdminLayout from '@/layouts/AdminLayout/AdminLayout';
import { StyledComponentsProvider } from '@/libs/styledComponents';
import { MSWComponent } from '@/mocks/MSWComponent';

const inter = Inter({ subsets: ['latin'] });

export const metadata: Metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <MSWComponent>
          <StyledComponentsProvider>
            <AdminLayout>{children}</AdminLayout>
          </StyledComponentsProvider>
        </MSWComponent>
      </body>
    </html>
  );
}


현재 이렇게 사용중인데 AdminLayout에 'use client'를 사용하지않으면, 아래와 같은 에러가 나오고
'use client' 를 사용하면 에러 없이 렌더링이 정상적으로 됩니다.

```

Server Error

Error: createContext only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/context-in-server-component

This error happened while generating the page. Any console logs will be displayed in the terminal window.

Call Stack

o

node_modules/styled-components/dist/styled-components.esm.js (1:15911)

(rsc)/./node_modules/styled-components/dist/styled-components.esm.js

next/server/vendor-chunks/styled-components.js (30:1)

__webpack_require__

next/server/webpack-runtime.js (33:42)

eval

webpack-internal:///(rsc)/./src/components/atoms/Text/Text.style.ts (5:75)

(rsc)/./src/components/atoms/Text/Text.style.ts

next/server/app/page.js (569:1)

__webpack_require__

next/server/webpack-runtime.js (33:42)

eval

webpack-internal:///(rsc)/./src/components/atoms/Text/Text.tsx (7:69)

(rsc)/./src/components/atoms/Text/Text.tsx

next/server/app/page.js (580:1)

__webpack_require__

next/server/webpack-runtime.js (33:42)

eval

webpack-internal:///(rsc)/./src/components/atoms/Text/index.ts (5:63)

(rsc)/./src/components/atoms/Text/index.ts

next/server/app/page.js (591:1)

__webpack_require__

next/server/webpack-runtime.js (33:42)

eval

webpack-internal:///(rsc)/./src/layouts/AdminLayout/AdminLayout.tsx (10:80)

(rsc)/./src/layouts/AdminLayout/AdminLayout.tsx

next/server/app/page.js (745:1)

__webpack_require__

next/server/webpack-runtime.js (33:42)

eval

webpack-internal:///(rsc)/./src/app/layout.tsx (10:90)

(rsc)/./src/app/layout.tsx

next/server/app/page.js (503:1)

Function.__webpack_require__

next/server/webpack-runtime.js (33:42)

async eq

/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js (35:401280)

async tr

/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js (35:405046)

async tn

/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js (35:405596)

async tu

/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js (35:409938)

async

/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js (35:410457)

```

궁금한 점이 3가지가 있는데 검색만으로는 이해가 잘안되서 질문드립니다ㅠ


1. AdminLayout이 'use client'를 선언하지 않고 서버 컴포넌트로 사용을 하여도 StyledComponentsProvider 가 'use client' 이기 때문에 클라이언트 컴포넌트의 자식으로 AdminLayout을 사용하면 AdminLayout도 자동으로 클라이언트 컴포넌트로 변경되는걸까요? 아니면 자식 요소로 사용하는것은 상관없이 import 해오는 경우만 클라이언트 컴포넌트에서 서버 컴포넌트를 불러오면 서버 컴포넌트가 클라이언트 컴포넌트가 되는걸까요?

2. 컴포넌트의 자식이 부모의 컴포넌트의 상태를 따라간다면, 만약 최상위 부모 (Layout)가 클라이언트 컴포넌트라면 어차피 AdminLayout 이나 불러오는 NavMenu 들을 서버 컴포넌트로 사용 못하는게 맞나요?

3. 강의상 진행할때는 문제 없었습니다. 현재 위에 질문드린 에러는 styled-components 때문에 createContext 는 use client에서만 사용할수있다라는 에러인거같은데 AdminLayOut이나 다른 페이지에서도 useContext를 사용하려하면 'use client'를 작성하여도 같은 에러가 나옵니다. 현재 말씀드린 정보로만으로는 에러의 문제점을 찾을순 없을까요?

react next.js react-query next-auth msw

답변 1

0

제로초(조현영)

  1. 클라이언트가 서버컴포넌트를 import하면 서버 컴포넌트가 클라이언트 컴포넌트가 됩니다. 서버컴포넌트가 클라이언트컴포넌트를 임포트하는건 아무 영향 없습니다.

  2. 네 그런데 서버컴포넌트를 import가 아니라 props로 전달하면 서버컴포넌트로 쓸 수 있습니다. children도 props라 서버컴포넌트를 전달 가능하고요. 레이아웃은 서버컴포넌트로 놔두는 게 좋습니다.

  3. 일단 서버 재시작 및 .next 삭제 해보시고 스타일드 컴포넌트를 쓴 곳을 전부 use client로 해보세요.

0

밍끼

import React from 'react';
import Logo from '@/components/atoms/Logo';
import Text from '@/components/atoms/Text';
import SideBarBody from '@/components/molecules/SideBarBody';
import SideBarFooter from '@/components/molecules/SideBarFooter';
import SideBarHeader from '@/components/molecules/SideBarHeader';
import SideBar from '@/components/organisms/SideBar/SideBar';
import { PropsWithRequiredChildren } from '@/types/common';
import LogoutButton from '../components/LogoutButton/LogoutButton';
import NavWrap from '../components/NavWrap/NavWrap';
import SearchInput from '../components/SearchInput/SearchInput';
import * as S from './AdminLayout.style';

export interface AdminLayoutProps extends PropsWithRequiredChildren {}

const AdminLayout = ({ children }: AdminLayoutProps) => {
  return (
    <>
      <SideBar>
        <SideBarHeader>
          <Logo />
          <Text
            $color="var(--color-white)"
            $bold={500}
            $size={1.8}
            $spacing={[4.8, 0, 0, 0]}
          >
            유저네임
          </Text>
          <Text $color="#F4F4F8" $bold={400} $size={1.4}>
            부가정보
          </Text>
        </SideBarHeader>
        <SideBarBody>
          <NavWrap />
        </SideBarBody>
        <SideBarFooter>
          <LogoutButton />
        </SideBarFooter>
      </SideBar>
      <S.Main>
        <SearchInput />
        {children}
      </S.Main>
    </>
  );
};

export default AdminLayout;

아하 답변 감사합니다. 현재 이렇게 style.ts에서 styled-component 를 불러와서 S. 으로 사용하여 Layout에 이벤트나 훅이 들어가지 않는데도 'use client'를 사용해야 에러가 일어나지않았던거군요

캡처링부분 질문있습니다.

0

76

2

깃에 소스코드를 찾을 수 없습니다.

0

113

2

useInfiniteQuery promise와 react use 사용시 페이지 무한 로딩

0

98

1

import 파일 경로를 찾지 못 해서 에러가 발생합니다.

0

111

2

css 라이브러리 추천 부탁드립니다

0

141

2

팔로우 추천 목록이 빈 배열로 들어옵니다.

0

133

1

게시물 업로드 시 userId가 undefined로 들어가는 오류

0

119

1

useSuspenseQuery 사용 시 SSR 401 이슈 관련

0

172

1

리액트 쿼리 useinfinitequery 무한스크롤 구현 시 페이지가 이동할 경우 데이터가 보존되게 할 수 있나요??

0

184

3

폴링이 필요없는 이유

0

93

2

next Request Memoization과 react cache

0

110

2

seo 최적화 기준은 데이터 fetching인가요 아님 데이터 렌더링인가요?

0

84

2

next.js 서버fetch 에러 fallback ui 구현 방법

0

173

2

프레임워크 여론 파악법

0

125

2

필터옵션이 많은 페이지에서 서버 fetch를 하는게 맞는걸까요??

0

103

2

서버 fetch suspense 로 감싸고 새로고침 시 잠시 빈 화면이 노출된 후 fallback ui가 노출됩니다.

0

102

2

template.tsx 내 서버fetch 응답값과 클라이언트 컴포넌트 상태값 싱크가 맞지 않는 이슈

0

66

2

Auth.js 사용 시 authorize 함수가 호출되지 않습니다

0

132

2

next.js 에서 로그인에 관하여

0

138

1

Next의 route handler에 대한 질문이 있습니다.

0

101

2

게시판 리스트 만들때 use client를 어디서부터 집어넣어야할지 모르겠습니다

0

98

2

프라이빗 폴더를 해야 하는 이유가 모호한 것 같아요.

0

85

2

vanilla-extract 못찾는 문제

0

230

2

fetch 캐싱과 revalidate 관련

0

85

2