import { createContext, useState } from "react";
export type State = {
darkMode: boolean;
toggleDarkMode: () => void;
};
//1.데이터를 담고 있는 컨텍스트
export const DarkModeContext = createContext<State>({
darkMode: false,
toggleDarkMode: () => {},
});
//2.데이터를 보여주도록하는 우산 --> 부모 우산 컴포넌트
export function DarkModeProvider({ children }: { children: React.ReactNode }) {
console.log(children);
const [darkMode, setDarkMode] = useState(false);
const toggleDarkMode = () => setDarkMode((mode) => !mode);
return (
//3. Provider로 감싸고 난뒤
//4 자식 컴포넌트와 공유하고 싶은 데이터가 있다면 value={{ darkMode, toggleDarkMode }}에 지정하면 됩니다.
<DarkModeContext.Provider value={{ darkMode, toggleDarkMode }}>
{children}
</DarkModeContext.Provider>
);
}
로직 설명 : 우리는 다크모드인지 아닌지 토글링하는 것 까지 자식 컴포넌트에서 다 활용하기를 원하므로 다크모드인지 아닌지 알 수 있는 상태 변수(darkMode)과 이것을 토글링하는 함수까지 전부 children에 제공하는 구조
import React, { useContext } from "react";
import { DarkModeContext, DarkModeProvider } from "./context/DarkModeContext";
import "./AppTheme.css";
//이용하고자하는 자식 컴포넌트에 우산을 씌우면 된다. DarkModeProvider
//최대한 필요한 곳에만 우산을 씌우자
const AppTheme = () => {
return (
<>
<Header />
<DarkModeProvider>
<Main />
</DarkModeProvider>
<Footer />
</>
);
};
function Header() {
return <header className='header'>Header</header>;
}
function Main() {
return (
<main>
Main
<Profile />
<Products />
</main>
);
}
function Profile() {
return (
<div>
Profile
<User />
</div>
);
}
function User() {
return <div>User</div>;
}
function Products() {
return (
<div>
Products
<ProductDetail />
</div>
);
}
function ProductDetail() {
//useContext를 사용하여 DarkModeContext를 사용할 것이라 명시해줍니다.
const { darkMode, toggleDarkMode } = useContext(DarkModeContext);
return (
<div>
Product Detail
<p>
DarkMode:
{darkMode ? (
<span style={{ backgroundColor: "black", color: "white" }}>Dark Mode</span>
) : (
<span>Light Mode</span>
)}
</p>
<button onClick={() => toggleDarkMode()}>Toggle</button>
</div>
);
}
function Footer() {
return <footer className='footer'>Footer</footer>;
}
export default AppTheme;