두 컴포넌트의 상태값을 공유해야한다면? 두 컴포넌트의 부모로 State를 올림 그리고 Props를 두 컴포넌트로 각각 전달
->Prop Drilling이 발생해서 비효율적임 - AppCount 예시
여러 컴포넌트들이 필요하다면 어플리케이션 전반적으로 필요한 경우 Context API를 사용할 수 있다.
언어, 테마(다크모드), 로그인/로그아웃여부 등등...
주의해야될 사항은 Context API우산으로 감싸진 부모, 자식들중 어느 하나라도 상태가 변경된다면 re-rendering이 되기때문에
빈번히 변경되야할 사항에는 Context API를 적용하지 않거나, Umbllera 테크닉을 사용하는 것이 좋다.
Context API 사용예제
DarkModeContext.jsx
import { createContext, useState } from "react";
export const DarkModeContext = createContext();
// createContext는 리액트에서 제공해주는 API임
// 일종의 데이터저장소 역할
// Context를 사용한다면, 아래와 같이 Provider도 같이 사용해줘야한다.
export function DarkModeProvider({ children }) {
// Provider은 일종의 실질적 우산 역할(하나의 부모 컴포넌트임)
const [darkMode, setDarkMode] = useState(false);
const toggleDarkMode = () => setDarkMode((mode) => !mode);
return (
<DarkModeContext.Provider value={{ darkMode, toggleDarkMode }}>
{/* <DarkModeContext.Provider value={{ darkMode: darkMode, toggleDarkMode: toggleDarkMode }}> */}
{/* 자식 컴포넌트(우산으로 감싸줄 컴포넌트)와 공유하고 싶은 데이터를 value에 써주는 것임 */}
{children}
</DarkModeContext.Provider>
);
}
- 다음과 같이 Context API는 컴포넌트 안에 같이 두기보다, 따로 작성해둔다.
AppTheme.jsx
import React, { useContext } from 'react';
import './AppTheme.css';
import { DarkModeContext, DarkModeProvider } from './context/DarkModeContext';
export default function AppTheme() {
return (
<DarkModeProvider>
<Header />
<Main />
<Footer />
</DarkModeProvider>
);
}
function Header() {
return <header className='header'>Header</header>;
}
function Main() {
return (
<main className='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() {
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>;
}
'React(Docs) > React(Practice)' 카테고리의 다른 글
Hydration (React ver.18) (0) | 2023.03.25 |
---|---|
AppForm_Form을 React에서 다루는 방법 (0) | 2022.12.14 |
AppMentors_Immer (0) | 2022.12.12 |
AppMentors_useReducer(구조분해할당) (0) | 2022.12.12 |
AppMentors_추가/삭제(filter, spread연산자, key) (0) | 2022.12.11 |