image

React Context API

태그
React
상세설명React Context API의 개념 및 사용법
작성일자2024.08.31

프로젝트 도중 컴포넌트에게 props를 사용하지 않고 필요한 데이터(state)를 쉽게 공유할 수 있는 방법을 찾던 중 React의 내장 API인 Context API를 사용하게 되어 관련된 정보 정리 해보았다.

Context API를 사용해야 하는 상황

동일한 데이터를 props를 통해 여러 컴포넌트를 거쳐야 하거나 다수의 컴포넌트에서 동일한 데이터가 필요한 경우에는 계속 props를 사용하여 넘겨 줘야되기 때문에 prop drilling(중첩된 여러 계층의 컴포넌트들에게 props를 전달하는 것) 이 발생한다.

⇒ Context API를 이용하면 전역적으로 데이터를 다룰 수 있어 컴포넌트의 깊이 여부와 무관하게 데이터가 필요한 컴포넌트에서만 불러다가 사용할 수 있다. Context API에서 State값을 변경하면, Provider로 감싼 모든 자식 컴포넌트들이 리렌더링되므로 전역 상태 관리를 위한 도구(=Redux, zustand)가 아닌, 데이터를 쉽게 전달하고 공유하기 위한 목적으로 사용하는 것이 적합하다. 그래서 자주 업데이트할 필요가 없는 데이터에 사용되기 때문에 주로 테마(라이트, 다크), 언어, 사용자 데이터 등에 사용된다.

Context API 사용법 in Next.js 13

  • React Context는 전역 데이터를 담고 있는 하나의 저장 공간으로 createContext 메서드를 사용하여 context 생성한다.
  • 생성한 context를 대상 컴포넌트에 값을 내려주기 위해서 Provider로 대상 컴포넌트를 감싸고 value로 전달할 props를 넘겨준다.
  • Context 생성 코드

    필자는 createContextd의 value를 관리하기 쉽게 컴포넌트로 분리 후 _app.tsx에 import해 사용했다.

  • ContextAPI를 설정해주기 위해 createContext를 import한다
  • export const GlobalDataContext = createContext(undefined); 를 설정한다
  • 전역으로 사용할 데이터를 value에 전달한다.
  • import { DataObject } from "@/InterfaceGather";
    import { useSession } from "next-auth/react";
    import { createContext, useEffect, useState } from "react";
    
    export const GlobalDataContext = createContext(undefined);
    
    export default function GlobalProvider({ children }: any) {
      const [data, setData] = useState<DataObject[]>([]);
      
       useEffect(() => {
        const fetchData = async (region: string) => {
          try {
            const response = await fetch(`/api/...`);
            const result = await response.json();
            setData(result);
          } catch (error) {
            console.error("Error:", error);
          }
        };
    
        if (region) {
          fetchData (region);
        }
      }, [region]);
    
      return (
        <GlobalDataContext.Provider value={data}>
          {children}
        </GlobalDataContext.Provider>
      );
    }
    

    GlobalProvider로 감싸진 컴포넌트 내에서 value값을 전역으로 사용할 수 있게 된다.

    //_app.tsx
    import React, { useEffect } from "react";
    import type { AppProps } from "next/app";
    import type { NextComponentType } from "next";
    import GlobalProvider from "@/components/GlobalProvider";
    
    export default function App({
      Component,
      pageProps: { session, ...pageProps },
      ...appProps
    }: CustomAppProps) {
      //..
      return (
        <>
          //..
          <GlobalProvider>
                <LayoutComponent>
                  <Global styles={[reset, SCoreDreamFont]} />
                  <Component {...pageProps} />
                </LayoutComponent>
           </GlobalProvider>
          //..
        </>
      );
    }

    Context 접근 코드

  • _app에서 export로 내보내준 GlobalDataContext값을 감싸준 컴포넌트 안에서 사용하고 싶은 곳에 import해다.
  • const { data }= useContext(GlobalDataContext); 이렇게 값을 가져오면 된다.
  • 주의할 점은 Provider로 감싸준 컴포넌트들은 해당 value값이 변할 때마다 같이 렌더링되게 된다
  • import { useContext } from "react";
    import { GlobalDataContext } from "@/components/GlobalDataContext";
    
    const SomeComponent = () => {
      const { data }= useContext(GlobalDataContext);
    
      if (!data) {
        throw new Error("GlobalDataContext must be used within a GlobalProvider");
      }
    
      return (
        <div>
          {/* data를 사용하여 UI를 구성 */}
        </div>
      );
    };