useContext 를 사용하여 drilling 이 없도록.
Children 컴포넌트에서 제약사항 없이 부모가 내려준 props 를 사용할 수 있도록 하겠습니다.

Result

1. useContext

useContextstore 와 기능이 매우 흡사함.
다만, 작은 규모의 프로젝트 혹은 개인프로젝트에서만 사용하는것을 권장한다.

그 외에는 store 를 사용하자 (redux, zustand ... etc)

그 이유는 아래 내용을 보면 알 수 있다. 가봅시다.

 

2. createContext & Provider

// 1. 테마 컨텍스트 생성
const ThemeContext = createContext();

//TypeScript
const ThemeContext = React.createContext<ThemeContextType | undefined>(
    undefined
);

const UseContext = () => {
    const [theme, setTheme] = useState("light");
    const toggleTheme = () => {
        setTheme(theme === "light" ? "dark" : "light");
    };
    return (
        <ThemeContext.Provider value={{ theme, toggleTheme }}>
            <ThemeComponent_1 />
        </ThemeContext.Provider>
    );
};

처음에 컴포넌트 바깥에서 Context를 생성 (createContext) 해주었다.

그 다음에는 

<ThemeContext.Provider value={{state, action}}>
	<ThemeComponent_1 />
</ThemeContext.Provider>

이렇게 Provider로 감싸서 props로 내려주었다. (여기까지는 일반 Props 와 뭐가다른데? 할 수 있다.)

차이점은 2번째 Drilling 에서부터 나타난다.

 

3. Childrens.

ThemeComponent_1 컴포넌트를 아래와 같이 선언하고 ThemeComponent_2에서 context로 내려준 props 들을 사용할 수 있다.

UseContext > ThemeComponent_1 > ThemeComponent_2 가 되는 꼴이다

//drilling 용 컴포넌트
const ThemeComponent_1 = () => {
    return <ThemeComponent_2 />;
};

//실제 context를 사용하는 컴포넌트
const ThemeComponent_2 = () => {
    const { theme, toggleTheme } = useContext(ThemeContext);

    return (
        <div
            className={`w-full mx-auto px-4 py-8 min-h-screen transition-all duration-300 ${
                theme === "light" ? "bg-gray-50" : "bg-gray-900 text-white"
            }`}
        >
            <h1>현재 테마: {theme}</h1>
            <button onClick={toggleTheme}>테마 변경</button>
        </div>
    );
};

[테마 변경] 버튼을 클릭 하면 light <> dark 로 전환이 되면서 배경색이 변경되도록 수정하였다.

전역적으로 사용하려면  App.jsx 혹은 Index.jsx 에 선언해놓고 Header.jsx 에서 사용하면 될 것이다.

 

Epiloge

확실히 useContext 를 통하여 사용할 수 있는 부분이 눈에 보인다. (가령 테마라던가...테마라던가...테마라던가.)

하지만 규모가 조금이라도 커지면 useContext 를 사용할 수 없을 것 같다. 
유지보수 측면에서 너무 큰 비용이 들어갈 것으로 보임.

그래서 결국에는 store (Redux, Zustand) 를 사용하게 될 것 같다.

 

전체 코드

TypeScript 로 작성해서 간단하게 type 을 선언하여 사용하였다.

import React, { useContext, useState } from "react";
import { FaSun, FaMoon } from "react-icons/fa";

interface ThemeContextType {
    theme: string;
    toggleTheme: () => void;
}

// 1. 테마 컨텍스트 생성
const ThemeContext = React.createContext<ThemeContextType | undefined>(
    undefined
);

const UseContext = () => {
    const [theme, setTheme] = useState("light");
    const toggleTheme = () => {
        setTheme(theme === "light" ? "dark" : "light");
    };
    return (
        <ThemeContext.Provider value={{ theme, toggleTheme }}>
            <ThemeComponent_1 />
        </ThemeContext.Provider>
    );
};

//drilling 용 컴포넌트
const ThemeComponent_1 = () => {
    return <ThemeComponent_2 />;
};

//실제 context를 사용하는 컴포넌트
const ThemeComponent_2 = () => {
    const context = useContext(ThemeContext);
    if (!context)
        throw new Error("ThemeContext must be used within ThemeProvider");

    const { theme, toggleTheme } = context;

    return (
        <div
            className={`w-full mx-auto px-4 py-8 min-h-screen transition-all duration-300 ${
                theme === "light" ? "bg-gray-50" : "bg-gray-900 text-white"
            }`}
        >
            <button
                onClick={toggleTheme}
                className={`p-2 rounded-full ${
                    theme === "light"
                        ? "bg-gray-200 hover:bg-gray-300"
                        : "bg-gray-700 hover:bg-gray-600"
                } transition-colors duration-200`}
                aria-label="테마 변경"
            >
                {theme === "light" ? (
                    <FaMoon className="w-5 h-5 text-gray-700" />
                ) : (
                    <FaSun className="w-5 h-5 text-yellow-300" />
                )}
            </button>
        </div>
    );
};

export default UseContext;

 

반응형

 

 

Tistory에서 코드를 작성하고 출력해놓은 결과를 보면 실망스럽기 짝이 없습니다. 

그래서 '플러그인'을 사용해서 <코드> 내용을 출력하면 나름 만족할만한 결과가 나옵니다.

그중에서 분명 syntax highlight 을 적용하였는데,

1. 플러그인 적용을 안하신 분 
2. '왜 코드가 너무 못났지?' 하시는 분

들을 위한 글입니다.

 

■ 1. 플러그인을 적용해주세요

티스토리 플러그인을 검색하면 나오는 'Syntax Highlight' 이라는 플러그인을 사용해주세요.

 

 

■ 2. '테마' 항목을 여러 가지로 바꿔보세요.

 

저는 Visual Studio로 적용해보았는데, 너무 이상하더라구요. 흰배경에 턱하니 그냥 글씨만 있고.

그래서 Atom One Dark로 변경하였습니다. (사실 바꾸기 귀찮아서 냅두다가 해보고 깨달았어요)

본인의 취향에 맞는 테마를 지정해보시길 바랍니다.

 

이상.

 

만약 글이 도움이 되셨다면, 광고 한 번 클릭해주시고 바로 ctrl+w로 창을 지워주시면 감사하겠습니다.

 

 

반응형

+ Recent posts