[새싹 프론트엔드] 8주차 - 3 Context
Context
• 어플리케이션에서 전반적으로 사용할 값을 저장 및 관리
• 예) 사용자의 언어, 로그인 상태, UI 테마 등 환경 설정
• 주의사항
• Context와 컴포넌트가 연동되면 컴포넌트를 재사용하기 어려움
• 자주 변경되는 상태인 경우, 사용하지 않는 것이 좋음
👉 Context 내부의 값이 변경되면 Context를 사용하는 모든 자식 컴포넌트들이 리렌더링 됨
일반적인 전역 상태 관리 흐름
컴포넌트 여기저기서 필요한 데이터가 있는 경우
• 주로 최상위 컴포넌트인 App의 state에 넣어서 관리
전달하면서 값을 넘겨줘야 함 (App에서 G로 한 방에 보내줄 방법이 없음)
단점 : 유지보수가 어려워짐
Props Drilling
실습) Props Drilling
App.js
function App() {
return <GrandParent value="Hello World!" />;
}
function GrandParent({ value }) {
return <Parent value={value} />;
}
function Parent({ value }) {
return <Child value={value} />;
}
function Child({ value }) {
return <Message value={value} />;
}
function Message({ value }) {
return <div>전달받은 데이터 : {value}</div>;
}
export default App;
실행 결과
Context를 사용한 전역 상태 관리 흐름
컴포넌트 여기저기서 필요한 데이터가 있는 경우
• Context를 생성하여 한번에 원하는 값을 전달 받음 (트리구조와는 별개)
A라는 거를 Context에 저장
Context 사용 방법
Context 객체 생성
• App.js
import { createContext } from 'react';
// MyContext 객체 생성
const MyContext = createContext();
Context 객체 내 Provider 컴포넌트를 통한 데이터 전달
Provider 컴포넌트의 하위 컴포넌트는 Context의 데이터에 접근 가능
(Provider는 내부적으로 자식을 가질 수 있음)
function App() {
return (
<MyContext.Provider value="Hello World!">
<GrandParent value="Hello World!"/>
);
}
Context 객체 내 Provider 컴포넌트는 그냥 들어있는 거니까 갖다 써 왜 들었는지는 신경쓰지말기
※ 프로젝트 폴더 안 context폴더 따로 하나 만들어서 그 안에다 파일 생성
컴포넌트, 리듀서도 마찬가지
grandparent가 직접 그 값을 가지게 된 것 (my context)
provider 쓸 애들만 지붕 씌워주기 - 안 쓸 애들까지 모조리 리렌더링 됨
<P~~>
<자식>
<P~~>
Context 사용 방법
App.js
실행 결과
실습) Context 파일 생성
Context.js
import { createContext } from "react";
export const MyContext = createContext("");
ParentComponent.js
import React from "react";
import { MyContext } from "./Context";
const ParentComponent = () => {
return (
<MyContext.Provider value="안녕하세요">
<ChildComponent />
</MyContext.Provider>
);
};
export default ParentComponent;
ChildComponent.js
import React, { useContext } from "react";
import { MyContext } from "./Context";
const ChildComponent = () => {
const value = useContext(MyContext);
return <div>전달받은 데이터 : {value}</div>;
};
export default ChildComponent;
실행 결과
Context 기본값 지정
createContext() 함수에 기본값 지정
• 자식 컴포넌트에서 useContext() 함수를 사용하고 있는데, 부모 컴포넌트가 Provider를 사용하지 않은 경우
• value 값을 지정해주지 않았기 때문에 해당 값이 출력될 자리에 아무것도 나타나지 않음
👉 기본값을 설정하면 이러한 문제를 방지할 수 있음
기본 값 지정 방법
const MyContext = createContext("Default Value"); |
매개변수로 초기값 넣기
실습) Context 기본값 지정
Context.js
import { createContext } from "react";
//재사용하기 위해 뺴주는 거
export const MyContext = createContext("기본값 지정");
ParentComponent.js
import React from "react";
import { MyContext } from "./Context";
import ChildComponent from "./ChildComponent";
const ParentComponent = () => {
return (
//<MyContext.Provider value="안녕하세요">
<ChildComponent />
//</MyContext.Provider>
);
};
export default ParentComponent;
실행결과
테마 변경
실습) 어플리케이션 전체 배경색 변경
ThemeContext.js
import { createContext } from "react";
export const ThemeContext = createContext();
App.js
function App() {
const [darkMode, setDarkMode] = useState(false);
return (
<ThemeContext.Provider value={{ darkMode, setDarkMode }}>
<HomeComponent />
</ThemeContext.Provider>
);
}
HomeComponent.js - 전체페이지 총괄(3단으로 쪼갬) 통째로 지붕 씌움
import { useContext } from "react";
import { ThemeContext } from "../1207/ThemeContext";
import HeaderComponent from "./HeaderComponent";
import MainComponent from "./MainComponent";
import FooterComponent from "./FooterComponent";
import "./HomeComponent.scss";
const HomeComponent = () => {
const data = useContext(ThemeContext);
console.log(data);
return (
<div className="container">
<HeaderComponent />
<MainComponent />
<FooterComponent />
</div>
);
};
export default HomeComponent;
HeaderComponent.js
import React, { useContext } from "react";
import { ThemeContext } from "./ThemeContext";
const HeaderComponent = () => {
const { darkMode, setDarkMode } = useContext(ThemeContext);
//dark모드는 False로 나옴
//dark모드를 True로 만듬
const toggleDarkMode = () => {
setDarkMode(!darkMode);
};
const theme = {
backgroundColor: darkMode ? "black" : "white",
color: darkMode ? "white" : "black",
};
return (
<div className="header" style={theme}>
헤더
{
darkMode ? (
<button className="toggleBtn" onClick={toggleDarkMode}>
😴
</button>
) : (
<button className="toggleBtn" onClick={toggleDarkMode}>
😵
</button>
)}
</div>
);
};
export default HeaderComponent;
MainComponent.js
import React, { useContext } from "react";
import { ThemeContext } from "./ThemeContext";
const MainComponent = () => {
const { darkMode } = useContext(ThemeContext);
const theme = {
backgroundColor: darkMode ? "black" : "white",
color: darkMode ? "white" : "black",
};
return (
<div className="main" style={theme}>
메인
</div>
);
};
export default MainComponent;
FooterComponent.js
import React, { useContext } from "react";
import { ThemeContext } from "./ThemeContext";
const FooterComponent = () => {
const { darkMode } = useContext(ThemeContext);
const theme = {
backgroundColor: darkMode ? "black" : "white",
color: darkMode ? "white" : "black",
};
return (
<div className="footer" style={theme}>
푸터
</div>
);
};
export default FooterComponent;
HomeComponent.scss
* {
margin: 0;
}
.container {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
}
@mixin flexCenter() {
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
}
.header {
@include flexCenter();
width: 100%;
height: 100px;
border-bottom: 3px solid gray;
}
.main {
@include flexCenter();
flex: 1;
}
.footer {
@include flexCenter();
width: 100%;
height: 100px;
border-top: 3px solid gray;
}
.toggleBtn {
background-color: transparent;
border: none;
font-size: 30px;
}
실행결과
예제 오류
1. ThemeContext 계속 찾지 못하는 상황 발생 styledcomponent라고 되어 있는 거
내 경로로(import { ThemeContext } from "./ThemeContext";) 재설정
2. export default HomeComponent; 안 해줘서 추가
3.scss 연결 안 됨 - 확장프로그램 설치 - className js마다 추가
도와주신 앞자리 천사님들 감사합니다

[실습회고]
인풋 값을 받아서 blue라고 입력하면 그대로 body backgroundColor를 바꾸는 문제였는데 풀다가 중간에 그 인풋 값을 어떻게 반영해야 할 지 길을 잃어서 수련이 부족하다고 생각 ,,, 풀이를 보니 너무 어렵게 접근한 것 같고 ,,,. 그래도 기 죽지 말자 처음 배우는건데 어떻게 첨부터 hook을 자유자재로 다루겠어!! 그냥 못하는 것을 받아들이고 노력하면 될 것.
풀이
const ColorBox = () => {
const value = useContext(ColorContext);
const boxStyle = {
background: value,
};
return <div style={boxStyle}></div>;
};
내 코드
const ColorBox = () => {
// const { changeBg, setchangeBg } = useContext(Color);
// const bgColor = changeBg;
// useEffect(() => {
// const inputColor = prompt("바꿀 배경 색상을 입력하세요");
// setchangeBg(inputColor);
// }, []);
일단 저 프롬프트는 다른 컴포넌트에 들어가 있어야 하고 바꾸고자 한 것은 변수에 담았어야 한다
아무튼 요상하게 코드 짜다 실패했으니 다시 개념을 다잡기
새싹DT 기업연계형 프론트엔드 실무 프로젝트 과정 8주차 블로그 포스팅