본문 바로가기
Next

Next.js - 서버 컴포넌트에서 useContext() 사용하기

by 새발개발JA 2023. 12. 31.
반응형

 

넥스트js는 서버컴포넌트와 클라이언트 컴포넌트로 나뉘어진다

그렇기 때문에 React 기반의 훅들을 사용할 때는 한번더 생각해보아야 한다

오늘은 useContext() 를 어떻게 사용하는 지 알아볼 것이다

 


Next.js - 서버 컴포넌트에서 useContext() 사용하기

 

 

 

 

 

리액트에서 전역 변수를 전달하기 위해 redux  / useContext 를 사용하였다

Next.js에서 useContext 를 사용하려고 하니 한가지 제약이 있었다

You are using createContext  in a Server Component but it only works in Client Components
→ 바로 클라이언트 컴포넌트에서만 사용이 가능하다는 것이다
 

createContext in a Server Component

Using App Router Features available in /app

nextjs.org

 

 

포트폴리오 모달의 page.tsx  서버 컴포넌트이다

자식으로는 클라이언트 컴포넌트인 <PortfolioMain> 과 <PortfolioInfo> 로 구성되어 있다

이 두 자매들에게 같은 변수안에 저장된 data 를 useContext 로 공유하려고 한다

 

 

서버 컴포넌트에서 useContext 를 사용하려면 방법이 아예 없는 것은 아니다

바로 <Provider>로 서버컴포넌트를 </Provider> 이렇게 감싸주면 가능하다

 

@modal/(.)portfolio/[id]/page.tsx

일단 서버컴포넌트에서 프로바이더 컴포넌트를 추가해주자

// server component
const PortfolioModal = async ({ params }: { params: { portfolioID: string }}) => {
  const { portfolioID } = params;
  const portfolio = await getPortfolio(portfolioID);

  return (
    <PortfolioProvider> // 프로바이더를 추가해주자
      <Modal>
        <div>
          <PortfolioMain portfolio={portfolio} />
          <PortfolioInfo contents={portfolio.contentHtml} />
        </div>
      </Modal>
    </PortfolioProvider>
  );
};

export default PortfolioModal;

 

 

components/portfolio/PortfolioContext.tsx

프로바이더 컴포넌트 내부에서는 

- 콘텍스트의 타입을 선언해주고, createContext 로 초기값을 함꼐 넣어준다

- 프로바이더 컴포넌트를 선언 후, 그 안에 context value 를 넣어준다

- 자식 컴포넌트 내에서 사용할 useContext 훅을 선언해준다

"use client";
import React, { Dispatch, SetStateAction, createContext, useContext, useState } from "react";

// 콘텍스트에 들어갈 값들의 타입 선언
interface PortfolioContextType {
  value: string;
  setValue: Dispatch<SetStateAction<string>>;
}

// 초기값 선언해주며 create ! 
const PortfolioContext = createContext<PortfolioContextType>({
  value: '디폴트 값입니다',
  setValue: () => {},
});

// 프로바이더 컴포넌트 셋업
export const PortfolioProvider = ({ children }: { children: React.ReactNode;}) => {
  const [value, setValue] = useState(''); // createContext 에서 지정해준 초기값이 우선 순위

  return (
    <PortfolioContext.Provider value={{ value, setValue }}>
      {children}
    </PortfolioContext.Provider>
  );
};

// 요건 클라이언트 컴포넌트 내부에서 호출할 훅!
export const usePortfolioContext = () => useContext(PortfolioContext);

 

 

components/portfolio/PortfolioMain.tsx

모달 내부의 자식컴포넌트에서 context  를 소환하여 value 를 사용할 수 있다

// 자식 컴포넌트 
"use client";
import React, { useState } from "react";

export const PortfolioMain = ({ children }: { children: React.ReactNode;}) => {
  const context = usePortfolioContext(); // 여기서 훅을 호출하여 사용

  return (
    <div>
      <button onClick={() => context.setValue('click')}> // context 안의 값(함수)를 사용
      	버튼
      </div>
      <div>{context.value}</div> // context 안의 값를 사용
    </div>
  );
};

 

 

반응형

댓글