ThemeProvider๋ฅผ ์ ์ฌ์ฉํ ๊น? ๐ง
ํ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉฐ ๊ณตํต color๋ฅผ ์ ์ํด ๋๊ณ ์ฐ๊ธฐ๋ก ํ์๋ค.
์ฐ๋ฆฌ ํ์ styled-components๋ฅผ ์ฌ์ฉํ๊ณ ์๋๋ฐ
๊ตฌ๊ธ๋ง์ ํตํด ThemeProvider๋ฅผ ํตํด ์ ์ญ์์ ๊ณต์ ํ ์ ์๋ค๋ ๋ด์ฉ์ ์ ํ๊ณ ๋ฐ๋ก ์ ์ฉํด ๋ณด๊ธฐ๋ก ํ๋ค.
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.jsx';
import { ThemeProvider } from 'styled-components';
import { theme } from './styles/theme.js';
createRoot(document.getElementById('root')).render(
<StrictMode>
<ThemeProvider theme={theme}>
<App />
</ThemeProvider>
</StrictMode>
);
์ต์๋จ์์ <ThemeProvider>๋ก children์ ๊ฐ์๋ค.
๊ทธ๋ฐ๋ฐ ๊ฐ์๊ธฐ ๋ ์๋ฌธ..
์ด์จ๋ theme.js ์์ฒด๋ฅผ export ํ๊ณ
์ฌ์ฉ์ฒ์์ importํด์ ํ์ํ ๋ ๋ฐ๋ก๋ฐ๋ก ์ฌ์ฉํ ์๋ ์๋ ๊ฑฐ ์๋๊ฐ?
์์์ ๋ณ๊ฒฝํ๋ค๊ณ ํ๋๋ผ๋ theme.js ์์ ์ฝ๋๋ฅผ ์์ ํ๋๊น ์ฌ์ฉํ๊ณ ์๋ ๊ณณ์ ๋ค ๊ฐ์ด ์์ ๋ ๊ฑฐ ์๋?
๊ทผ๋ฐ ์ ๊ตณ์ด ThemProvider๋ฅผ ์จ์ผํ์ง..? ๐ค
๊ทธ๋์ ThemeProvider๋ฅผ ์ฌ์ฉํด์ผ ํ๋ ์ด์ ๋ฅผ ์ฐพ์๋ดค๋ค.
โจ ThemeProvider๋ฅผ ์ฌ์ฉํ๋ ์ด์
1. React Context ํ์ฉ
ThemeProvider๋ ๋ด๋ถ์ ์ผ๋ก React Context API๋ฅผ ํ์ฉํ๋ค.
๋ฐ๋ผ์ ์ปดํฌ๋ํธ ํธ๋ฆฌ ๋ด์ ๋ชจ๋ ์์ ์ปดํฌ๋ํธ๋ค์๊ฒ ์๋์ผ๋ก ๊ฐ์ ์ ๋ฌํ ์ ์๋ค.
์ด๋ฅผ ํตํด์ ํ์ ์ปดํฌ๋ํธ๋ค์ theme.js ํ์ผ์ ์ผ์ผ์ด importํ์ง ์์๋ ์ฝ๊ฒ theme์ ์ ๊ทผํ์ฌ ๊ฐ์ ์ฌ์ฉํ ์ ์๋ค.
2. ๋์ ํ ๋ง ๋ณ๊ฒฝ
ThemeProvider๋ฅผ ์ฌ์ฉํ๋ฉด ๋์ ์ผ๋ก ํ ๋ง๋ฅผ ์ฝ๊ฒ ๋ณ๊ฒฝํ ์ ์๋ค.
์๋ฅผ ๋ค์ด ๋คํฌ ๋ชจ๋ / ๋ผ์ดํธ ๋ชจ๋๋ฅผ ์ ํํ๊ณ ์ถ๋ค๋ฉด ThemeProvider์ theme์ ๊ฐ์ ๋์ ์ผ๋ก ๋ณ๊ฒฝํ ์ ์๋ค.
์ด ๋ณ๊ฒฝ์ด ์๋์ผ๋ก ๋ชจ๋ ์์ ์ปดํฌ๋ํธ์ ์ ์ฉ๋๊ธฐ ๋๋ฌธ์
ํ ๋ง๋ฅผ ๋ณ๊ฒฝํ ๋ importํ theme.js๋ฅผ ์ผ์ผ์ด ์์ ํ ํ์ ์์ด ์ปดํฌ๋ํธ ์ํ๋ ์ปจํ ์คํธ๋ฅผ ํตํด ์ฝ๊ฒ ์ ์ฉํ ์ ์๋ค.
3. ํ ๋ง ๊ฐ ๊ด๋ฆฌ์ ์ผ๊ด์ฑ
theme.js์์ theme ๊ฐ์ ์ง์ ๊ด๋ฆฌํ๊ณ importํด์ ์ฌ์ฉํ๋ ๋ฐฉ์์ ์์ ํ๋ก์ ํธ์์๋ ๊ด์ฐฎ์ง๋ง ํ๋ก์ ํธ ๊ท๋ชจ๊ฐ ์ปค์ง์๋ก ๋ณต์กํด์ง ์ ์๋ค. ์ฌ๋ฌ ์ปดํฌ๋ํธ์์ import๋ฅผ ๋ฐ๋ณตํ๊ฒ ๋๊ณ , ์ด ๊ฐ๋ค์ด ์ค๋ณต๋๊ฑฐ๋ ๊ด๋ฆฌ๊ฐ ์ด๋ ค์์ง ์ ์๋ค.
ThemeProvider๋ ๊ทธ๋ฐ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ๊ณ , ์ ์ญ์ ์ผ๋ก ํ ๋ง๋ฅผ ์ผ๊ด๋๊ฒ ๊ด๋ฆฌํ ์ ์๋๋ก ๋์์ค๋ค.
์ผ๋จ ์ด์ ๋ฅผ ์ ๋ฆฌ๋ ํด๋ดค๋๋ฐ ์ฌ์ค ํฌ๊ฒ ์๋ฟ์ง๊ฐ ์์๋ค.
๋์ ํ ๋ง ๋ณ๊ฒฝ?
export const lightTheme = {
background: "#fff",
color: "#000",
};
export const darkTheme = {
background: "#000",
color: "#fff",
};
์ด๋ ๊ฒ theme.js์ ์ ์๋์ด ์๋ค๊ณ ๊ฐ์ ํ๊ณ
๋ค๋ฅธ ์ปดํฌ๋ํธ์์ ์ฌ์ฉํ ๋
export default function Component () {
const [isDark,setIsDark] = useState(false);
return(
<h1 style={{ color : isDark ? theme.colors.dakr : theme.colors.light}}>Hello!</h1>
<button>{isDark ?'๋คํฌ' :'๋ผ์ดํธ'}๋ชจ๋ ์ ํ</button>
)
}
์ด๋ ๊ฒ ์ฌ์ฉ๋ ํ ๋ฐ ์ด๊ฒ๋ ๋์ ํ ๋ง ๋ณ๊ฒฝ์ด ๋๋ ๊ฑฐ ์๋๊ฐ?
๋ผ๊ณ ์๊ฐํ๋ค.
์๋ฌด๋ฆฌ ์๊ฐํด๋ ์ดํด๊ฐ ๋์ง ์์ chatGPT์๊ฒ ์์๋ฅผ ๋ง๋ค์ด ๋ฌ๋ผ๊ณ ์์ฒญํ๋ค.
โจ ThemeProvider ์์
export const lightTheme = {
background: "#fff",
color: "#000",
};
export const darkTheme = {
background: "#000",
color: "#fff",
};
import { createContext, useContext, useState } from "react";
import { lightTheme, darkTheme } from "./theme";
const ThemeContext = createContext();
export const ThemeProvider = ({ children }) => {
const [isDark, setIsDark] = useState(false);
const theme = isDark ? darkTheme : lightTheme;
return (
<ThemeContext.Provider value={{ theme, isDark, setIsDark }}>
{children}
</ThemeContext.Provider>
);
};
export const useTheme = () => useContext(ThemeContext);
import { ThemeProvider } from "./ThemeContext";
import MyComponent from "./MyComponent";
const App = () => {
return (
<ThemeProvider>
<MyComponent />
</ThemeProvider>
);
};
export default App;
import { useTheme } from "./ThemeContext";
const MyComponent = () => {
const { theme, setIsDark, isDark } = useTheme();
return (
<div style={{ background: theme.background, color: theme.color }}>
<button onClick={() => setIsDark((prev) => !prev)}>
Toggle Theme
</button>
<p>Hello, Theme!</p>
</div>
);
};
export default MyComponent;
์ฝ๋๋ฅผ ๋ณด๋ ๋จ๋ฒ์ ์ดํด๊ฐ ๋์๋ค.
๋ผ์ดํธ / ๋คํฌ ํ ๋ง ๋ชจ๋๋ ๋ชจ๋ ํ์ด์ง์ ์ํฅ์ ๋ฏธ์น๋๋ฐ
์ผ์ผ์ด importํด์ ์ฌ์ฉํ ๊ฒฝ์ฐ ๋ชจ๋ ์ปดํฌ๋ํธ ๋ด๋ถ์์ ํ ๋ง ๋ชจ๋์ ๋ํ state๋ฅผ ๊ด๋ฆฌํด์ค์ผ ํ๋ค.
ํ์ง๋ง ThemeProvider๋ฅผ ์ฌ์ฉํ๋ฉด Provider ํจ์ ๋ด๋ถ์์ state๋ฅผ ๋ง๋ค์ด ๊ด๋ฆฌํ๊ณ
์ ์ญ ์ํ์์ ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ ์ฝ๋๊ฐ ํจ์ฌ ๋ ๊ฐ๊ฒฐํ๊ณ ์ ์ง๋ณด์๋ ํธํ๋ค.
์ํ! contextAPI์ฒ๋ผ ์๋ํ๋๊ตฌ๋~
๊ทธ๋ฌ๋ฉด contextAPI๋ก ๊ตฌํํด๋ ๋๋๋ฐ ์ ThemeProvider๋ฅผ ์ธ๊น? ๐ค
โจ styled-components์ ThemeProvider vs Context API
styled-components ๊ฐ์ CSS-in-JS ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์๋ ์์ฒด์ ์ธ ThemeProvider๋ฅผ ์ ๊ณตํ๋๋ฐ, ์ด๊ฒ Context API์ ๊ฑฐ์ ๋์ผํ ์ญํ ์ ํ๋ค. ํ์ง๋ง ๋ค์๊ณผ ๊ฐ์ ์ฐจ์ด๊ฐ ์๋ค.
โ styled-components์ ThemeProvider ์ฅ์
- styled-components๋ ์๋์ผ๋ก theme ๊ฐ์ props.theme ํํ๋ก ์ ๋ฌํด ์ฃผ๊ธฐ ๋๋ฌธ์ ์คํ์ผ ์ ์๊ฐ ํจ์ฌ ๊น๋ํด์ง๋ค.
const Home = () => {
return <StHome>hello</StHome>;
};
export default Home;
const StHome = styled.div`
background-color: ${(props) => props.theme.colors.primary};
`;
์๋ฅผ ๋ค๋ฉด ์์ ๊ฐ์ด ์ background-color๋ฅผ props๋ก ์ง์ ์ ๋ฌํด ์ฃผ์ง ์์๋ theme์ ์ ๊ทผํ์ฌ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค.
- styled-components ๋ด๋ถ์ ์ผ๋ก "์คํ์ผ ์บ์ฑ"๊ณผ "์คํ์ผ ์ฌ์ฌ์ฉ"์ ์๋์ผ๋ก ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์ ์คํ์ผ ๋ณ๊ฒฝ๋ง ๊ฐ์งํ๊ณ ์ปดํฌ๋ํธ ์์ฒด๋ ๋ฆฌ๋ ๋๋ง์ด ๋์ง ์์ ์ฑ๋ฅ์ ๋ ์ข๋ค.
- css-in-js ๋ฐฉ์๊ณผ ์์ฐ์ค๋ฝ๊ฒ ์ด์ธ๋ ค์ ์ฌ์ฉ์ด ํธ๋ฆฌํจ.
โ Context API๋ง์ผ๋ก ์คํ์ผ์ ๊ด๋ฆฌํ ๋์ ๋จ์
- styled-components, Emotion, MUI ๋ฑ์ ํ ๋ง ์์คํ ๊ณผ ํตํฉํ๊ธฐ ์ด๋ ต๋ค → ํด๋น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ ๊ธฐ๋ณธ์ ์ผ๋ก ThemeProvider๋ฅผ ์ฌ์ฉํ๋๋ก ์ค๊ณ๋์ด ์์.
- ๋ฆฌ๋ ๋๋ง ๋น์ฉ์ด ์ฆ๊ฐํ ์ ์๋ค → theme ๊ฐ์ด ๋ฐ๋ ๋, Context๋ฅผ ์ฌ์ฉํ๋ ๋ชจ๋ ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง ๋ ์ ์์. (React์ useContext๋ ๊ฐ์ด ๋ฐ๋๋ฉด ํด๋น Context๋ฅผ ๊ตฌ๋ ํ๋ ๋ชจ๋ ์ปดํฌ๋ํธ๋ฅผ ๋ค์ ๋ ๋๋งํจ)
- CSS-in-JS ๋ฐฉ์๋ณด๋ค ์ฝ๋๊ฐ ์ง์ ๋ถํด์ง ์ ์๋ค → style={{ color: theme.color }} ๊ฐ์ ์ธ๋ผ์ธ ์คํ์ผ์ ๊ณ์ ์จ์ผ ํด์ ์คํ์ผ ์ฝ๋๊ฐ ๊ธธ์ด์ง๊ณ ๊ฐ๋ ์ฑ์ด ๋จ์ด์ง ์ ์์.
์ฌ๊ธฐ๊น์ง ThemeProvider์ ๋ํด ์์๋ณด์๋ค.
์ญ์ ๋ค ์กด์ฌ์ ์ด์ ๊ฐ ์๋ค(?)
styled-components๋ ์ฒ์ ์ฌ์ฉํด ๋ณด๋๋ฐ ์ค๋์ ๊ธฐ์ ์ผ๋ก ์ข ๋ ์นํด์ก์ผ๋ฉด ์ข๊ฒ ๋ค..๐