๐ React์ Context์ ๋ํด ํบ์๋ณด์!
React ์ฑ์ ๊ฐ๋ฐํ๋ค ๋ณด๋ฉด ๋ฐ์ดํฐ๋ฅผ โ๋ถ๋ชจ โ ์์ โ ์์โ ์์ผ๋ก ์ค์ค์ด ๋ด๋ ค์ค์ผ ํ ๋๊ฐ ์์ด์. ์ด๋ ์ฐ๋ฆฌ๋ โprops drillingโ์ด๋ผ๋ ์ฌ๋ฏธ์๋ ๋์ด์ ๋น ์ง๊ฒ ๋ฉ๋๋ค. ์ปดํฌ๋ํธ ๊ฐ ๋ฐ์ดํฐ ์ ๋ฌ์ด ๋๋ฌด ๊ท์ฐฎ๊ณ ๋ณต์กํ๊ฒ ๋๊ปด์ง ๋, ๋ฐ๋ก React Context๊ฐ ๊ตฌ์ธ์ฃผ์ฒ๋ผ ๋ฑ์ฅํฉ๋๋ค!
์ค๋์ React Context์ ๋ชจ๋ ๊ฒ์ ํํ ํธ์ด๋ด ๋๋ค. Context๊ฐ ๋ญ์ง, ์ ์จ์ผ ํ๋์ง, ์ด๋ป๊ฒ ์ฐ๋์ง, ๊ทธ๋ฆฌ๊ณ ์ค์ ์์ ์ ์ฉํ ํ๊น์ง! ๐
๐ Context๋?
Context๋ React ์ฑ์์ ์ปดํฌ๋ํธ ํธ๋ฆฌ ์ ์ฒด์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ ์ ์๋ ๊ธฐ๋ฅ์ ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก props๋ฅผ ์ฌ์ฉํด ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ์ง๋ง, ์ค๊ฐ์ ์๋ ๋ถํ์ํ ์ปดํฌ๋ํธ๋ค์ ๊ฑฐ์น์ง ์๊ณ ๋ฐ๋ก ํ์ํ ์ปดํฌ๋ํธ์๊ฒ ๋ฐ์ดํฐ๋ฅผ ์ค ์ ์์ฃ .
๐ก ๊ณต์ ์ค๋ช
Context provides a way to pass data through the component tree without having to pass props down manually at every level.
๐ ๋ฒ์ญ: Context๋ ์ปดํฌ๋ํธ ํธ๋ฆฌ ์ ์ฒด์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ฉฐ, ๋งค ๋จ๊ณ๋ง๋ค props๋ฅผ ์๋์ผ๋ก ์ ๋ฌํ ํ์๊ฐ ์๊ฒ ํด์ค๋๋ค.
๐ค ์ Context๋ฅผ ์จ์ผ ํ ๊น?
- Props Drilling ๋ฐฉ์ง
- ์ค๊ฐ ์ปดํฌ๋ํธ๊ฐ ํ์ ์๋ ๋ฐ์ดํฐ๋ฅผ ์ต์ง๋ก props๋ก ๋ฐ์ ์ ๋ฌํด์ผ ํ๋ ์ํฉ์ ์์ฑ๋๋ค.
- ๊ธ๋ก๋ฒ ์ํ ๊ด๋ฆฌ
- ํ ๋ง, ์ฌ์ฉ์ ์ธ์ฆ, ์ธ์ด ์ค์ ๋ฑ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ญ์์ ๊ณต์ ๋๋ ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ ๋ ์ ์ฉํฉ๋๋ค.
- ์ฝ๋ ๊ฐ๊ฒฐํ
- props๋ก ๋ฐ์ดํฐ๋ฅผ ๊ณ์ ์ ๋ฌํ๋ ๋ฐ๋ณต์ ์ธ ์์ ์ ์ค์ด๊ณ , ์ฝ๋์ ๊ฐ๋ ์ฑ์ ๋์ ๋๋ค.
๐ณ Context์ ๊ธฐ๋ณธ ๊ตฌ์กฐ
React Context๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด 3๊ฐ์ง ๋จ๊ณ๋ฅผ ๋ฐ๋ผ์ผ ํฉ๋๋ค:
- Context ์์ฑ
- React.createContext()๋ก Context๋ฅผ ๋ง๋ญ๋๋ค.
- Provider๋ก ๊ฐ ์ ๋ฌ
- Context.Provider๋ฅผ ์ฌ์ฉํด ๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํฉ๋๋ค.
- Consumer๋ก ๊ฐ ์ฌ์ฉ
- Context.Consumer๋ useContext ํ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
๐ ๏ธ ๊ธฐ๋ณธ ์์
import React, { createContext, useContext } from 'react';
// 1. Context ์์ฑ
const ThemeContext = createContext();
// 2. Provider๋ก ๊ฐ ์ ๋ฌ
function ThemeProvider({ children }) {
const theme = 'dark';
return (
<ThemeContext.Provider value={theme}>
{children}
</ThemeContext.Provider>
);
}
// 3. Consumer๋ก ๊ฐ ์ฌ์ฉ
function ThemedComponent() {
const theme = useContext(ThemeContext);
return <div>The current theme is {theme}</div>;
}
function App() {
return (
<ThemeProvider>
<ThemedComponent />
</ThemeProvider>
);
}
export default App;
โจ Context ์ฃผ์ ๊ฐ๋
1. Provider
Provider๋ Context์ ๊ฐ์ ๊ณต๊ธํ๋ ์ญํ ์ ํฉ๋๋ค. Context๋ฅผ ์ฌ์ฉํ๋ ๋ชจ๋ ์ปดํฌ๋ํธ๋ Provider๊ฐ ์ ๊ณตํ ๊ฐ์ ์ฐธ์กฐํฉ๋๋ค.
<ThemeContext.Provider value="light">
<ChildComponent />
</ThemeContext.Provider>
2. Consumer
Consumer๋ Context ๊ฐ์ ์ฝ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. useContext ํ ์ผ๋ก ๋ ๊ฐํธํ๊ฒ ๋์ฒดํ ์ ์์ฃ .
<ThemeContext.Consumer>
{(value) => <div>The theme is {value}</div>}
</ThemeContext.Consumer>
3. useContext
React์ useContext ํ ์ Context ๊ฐ์ ์ฝ๊ฒ ๊ฐ์ ธ์ค๊ฒ ํด์ค๋๋ค. ํจ์ฌ ๊ฐ๋จํ์ฃ .
const value = useContext(MyContext);
๐ ์ค์ ํ์ฉ ์์
1. ๋คํฌ ๋ชจ๋ ํ ๋ง ๊ด๋ฆฌ
import React, { createContext, useContext, useState } from 'react';
// Context ์์ฑ
const ThemeContext = createContext();
function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
const toggleTheme = () => {
setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light'));
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
}
function ThemeToggleButton() {
const { theme, toggleTheme } = useContext(ThemeContext);
return (
<button onClick={toggleTheme}>
Toggle to {theme === 'light' ? 'dark' : 'light'}
</button>
);
}
function ThemedComponent() {
const { theme } = useContext(ThemeContext);
return <div>The current theme is {theme}</div>;
}
function App() {
return (
<ThemeProvider>
<ThemeToggleButton />
<ThemedComponent />
</ThemeProvider>
);
}
export default App;
2. ์ฌ์ฉ์ ์ธ์ฆ ๊ด๋ฆฌ
import React, { createContext, useContext, useState } from 'react';
// Context ์์ฑ
const AuthContext = createContext();
function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const login = (username) => setUser({ username });
const logout = () => setUser(null);
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
}
function UserProfile() {
const { user } = useContext(AuthContext);
return <div>{user ? `Logged in as ${user.username}` : 'Not logged in'}</div>;
}
function LoginButton() {
const { login } = useContext(AuthContext);
return <button onClick={() => login('ReactDeveloper')}>Login</button>;
}
function LogoutButton() {
const { logout } = useContext(AuthContext);
return <button onClick={logout}>Logout</button>;
}
function App() {
return (
<AuthProvider>
<UserProfile />
<LoginButton />
<LogoutButton />
</AuthProvider>
);
}
export default App;
โ ๏ธ Context ์ฌ์ฉ ์ ์ฃผ์์ฌํญ
- ๋ถํ์ํ ๋ ๋๋ง
- Context ๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด Provider ํ์์ ๋ชจ๋ ์ปดํฌ๋ํธ๊ฐ ๋ค์ ๋ ๋๋ง๋ฉ๋๋ค.
- ํด๊ฒฐ์ฑ : ๊ฐ์ด ์์ฃผ ๋ณ๊ฒฝ๋๋ ๊ฒฝ์ฐ, Context ๋์ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(Redux, Zustand ๋ฑ)๋ฅผ ๊ณ ๋ คํ์ธ์.
- ๋ณต์กํ ๊ตฌ์กฐ
- Context๋ฅผ ์ฌ๋ฌ ๊ฐ ์ค์ฒฉํด์ ์ฌ์ฉํ๋ฉด ์ฝ๋๊ฐ ๋ณต์กํด์ง ์ ์์ต๋๋ค.
- ํด๊ฒฐ์ฑ : Provider๋ฅผ ์ฌ๋ฌ ์ปดํฌ๋ํธ๋ก ๋๋์ด ๊ด๋ฆฌํ๊ฑฐ๋, useReducer์ ํจ๊ป ์ฌ์ฉํ์ธ์.
๐ฏ ์์ฝ
- Context๋?
- ์ปดํฌ๋ํธ ํธ๋ฆฌ ์ ์ฒด์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ React์ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ
- ์ธ์ ์ฐ๋?
- Props drilling์ ๋ฐฉ์งํ๊ณ , ๊ธ๋ก๋ฒ ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํด์ผ ํ ๋
- ๊ตฌ์กฐ์ ํต์ฌ ๊ฐ๋
- createContext, Provider, useContext
- ์ค์ ์์ ์ ์ฉํ ํจํด
- ํ ๋ง ๊ด๋ฆฌ, ์ฌ์ฉ์ ์ธ์ฆ ๋ฑ.
๐ท ์ ์ค์ ๊ฐ๋ฐ์๊ฐ ๋์ด๋ด ์๋น! ๐ท