저번에는 https://velog.io/@kiminn/React-useContext란 를 통해서 useContext
에 대해서 알아봤습니다
이제 useContext
를 사용하여 사용자 입장에서 너무나도 당연해져버린 웹 페이지의 다크 모드 테마를 구현해보겠습니다
App.js(상태) > Page.jsx(X) > Header & Content & Footer(상태)
// App.js
import { useState } from 'react';
import './App.css';
import Page from './components/Page';
function App() {
const [isDark, setIsDark] = useState(false); // 기본적으로 isDark가 꺼져있음(light mode)
return <Page isDark={isDark} setIsDark={setIsDark}/>;
}
export default App;
아래 코드는 App.js에서 만들어진 상태(isDark)를 필요가 없는 중간 컴포넌트인 Page.jsx가 전달받은 모습입니다 => 그럴 필요가 있나? => (X)
// Page.jsx
import Content from './Content';
import Footer from './Footer';
import Header from './Header';
const Page = ({isDark, setIsDark}) => {
return (
<div className="page">
<Header isDark={isDark} />
<Content isDark={isDark} />
<Footer isDark={isDark} setIsDark={setIsDark} />
</div>
);
};
export default Page;
앱의 규모가 커지면서 이러한 중간 컴포넌트들이 만약 수십 개가 된다면, 일일이 찾아다니면서 디버깅하고 유지보수하는 과정이 아주 끔찍해질 것입니다
먼저 isDark는 테마에 대한 정보를 담고있는 것으로 전역적인 데이터 관리가 필요합니다
=> useContext
사용하여 관리
🌱 createContext : Context 객체 생성
// ThemeContext.js import { createContext } from "react"; export const ThemeContext = createContext(null);
🌱 Provider : 생성한 context(상태)를 자식 컴포넌트에 공유
import { useState } from 'react'; import './App.css'; import Page from './components/Page'; import { ThemeContext } from './context/ThemeContext'; function App() { const [isDark, setIsDark] = useState(false); // lightmode return ( <ThemeContext.Provider value={{ isDark, setIsDark }}> {/* value 안에는 전달하고자하는 데이터를 집어넣는다 모든 하위컴포넌트에 전달해야하는 isDark, setIsDark 넣어주기 props를 사용하지않고 접근할 수 있다 */} <Page /> </ThemeContext.Provider> ); } export default App;
// Header.jsx
import React, { useContext } from 'react';
import { ThemeContext } from '../context/ThemeContext';
// props로 전달됐던 ()안의 isDark 삭제
const Header = () => {
const { isDark } = useContext(ThemeContext);
return (
<header
className="header"
style={{
backgroundColor: isDark ? 'black' : '#ff7cc8',
color: isDark ? 'white' : '#2d2d2d',
}}
>
<h1>hi, user</h1>
</header>
);
};
export default Header;
// Context.jsx
import React, { useContext } from 'react';
import { ThemeContext } from '../context/ThemeContext';
// props로 전달됐던 ()안의 isDark 삭제
const Content = () => {
const { isDark } = useContext(ThemeContext);
return (
<div
className="content"
style={{
backgroundColor: isDark ? '#333333' : '#ffebeb',
color: isDark ? '#ffffff' : '#ff0095',
}}
>
<p>user, Click the button below ↘️</p>
</div>
);
};
export default Content;
// Footer.jsx
import React, { useContext } from "react";
import { ThemeContext } from "../context/ThemeContext";
// props로 전달됐던 ()안의 isDark, setIsDarkt삭제
const Footer = () => {
const {isDark, setIsDark} = useContext(ThemeContext);
const toggleTheme = () => {
setIsDark(!isDark);
};
return (
<footer
className="footer"
style={{
backgroundColor: isDark ? 'black' : '#ff7cc8',
color: isDark ? 'white' : '#333333',
}}
>
<button className="button" onClick={toggleTheme}>
Dark Mode
</button>
</footer>
);
};
export default Footer;
// Page.jsx
import Content from './Content';
import Footer from './Footer';
import Header from './Header';
const Page = () => {
return (
<div className="page">
<Header />
<Content />
<Footer />
</div>
);
};
export default Page;
그러면 이렇게 하단의 버튼을 눌렀을 때 다크모드로 전환이 되는 페이지가 구현됩니다
같은 방법으로 user의 이름도 관리할 수 있습니다
// UserContext.js
import { createContext } from "react";
export const UserContext = createContext(null);
// App.js
import { useState } from 'react';
import './App.css';
import Page from './components/Page';
import { ThemeContext } from './context/ThemeContext';
import { UserContext } from './context/UserContext';
function App() {
const [isDark, setIsDark] = useState(false);
return (
<UserContext.Provider value={'kimi'}> // userContext
<ThemeContext.Provider value={{ isDark, setIsDark }}>
<Page />
</ThemeContext.Provider>
</UserContext.Provider>
);
}
export default App;
// Header.jsx
import React, { useContext } from 'react';
import { ThemeContext } from '../context/ThemeContext';
import { UserContext } from '../context/UserContext';
const Header = () => {
const { isDark } = useContext(ThemeContext);
const user = useContext(UserContext);
return (
<header
className="header"
style={{
backgroundColor: isDark ? 'black' : '#ff7cc8',
color: isDark ? 'white' : '#2d2d2d',
}}
>
<h1>hi, {user}</h1>
</header>
);
};
export default Header;
위와 같은 방법으로 Content도 수정하면 user(사용자 이름)부분도 useContext를 사용하여 관리할 수 있습니다
별 코딩님의 유튜브 강의
https://www.youtube.com/watch?v=LwvXVEHS638
참고한 사이트
https://jaylee-log.tistory.com/55
잘보고갑니다~