일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- css기초
- nodejs파일업로드
- cookie-parser 만들어보기
- JWT 만들어보기
- useEffect clean up
- express session
- 블록 만들기
- Uncaught Error: could not find react-redux context value; please ensure the component is wrapped in a <Provider>
- buffer.from
- ws 라이브러리
- 라우터미들웨어 분리
- express router
- express.static
- 아이디 중복체크기능
- mysql wsl
- 라우터와 미들웨어
- express실행
- JWT 하드코딩
- 라우터 분리
- 라우트 매개변수
- useContext
- next 매개변수
- node.js path
- 세션으로 로그인 구현
- 비동기파일업로드
- javascript기초
- FormData()
- JWT 로그인 기능 구현
- 시퀄라이즈 기본설정
- OAuth 카카오
- Today
- Total
즐코
Context API 복습 본문
redux라이브러리를 사용하겠지만,, contextAPI 복습을 해보았다.
원래 context는 Redux에서 나온 개념인데, redux 만든 사람이 react팀으로 가면서 해당 context API 를 만들었다는 얘기가 있다.
암튼, 전역적으로 여러 컴포넌트 내에서 쓰일 데이터가 있다면 이 context API를 사용하는 게 좋다.
ex) 로그인한 사용자 정보, 페이지 테마 (다크/라이트모드), 사용언어 등등..
자세히 예를 들자면,
App -> Toolbar -> ThemeButton 이런식으로 컴포넌트들이 있고, ThemeButton만 App의 특정 props가 필요하다고 가정한다.
이 때, context API 가 없었다면, props 가 필요없는 Toolbar 컴포넌트가 쓸데없이 그 props를 받아서 자식 컴포넌트인 ThemeButton에게 전달해줘야한다.
그렇다고 props를 사용하지 않는 건 아니라고 한다.
- context 를 사용하면 컴포넌트를 재사용하기 어려워진다고 한다.
- context 를 사용하는 이유가 prop drilling 을 피하기 위한 목적이라면 Component Composition(컴포넌트 합성) 을 고려해보라고 한다. 컴포넌트 합성에 관하여 따로 포스팅하였다.
1. 전역상태를 담을 Context 파일 따로 만들기
우선 src-context를 관리할 폴더를 따로 만들고 그 안에 전역으로 쓰고자하는 context들별로 파일을 만들어준다.
테마 관리용 컨텍스트 / 유저정보 컨텍스트 파일을 만들었음
createContext()
각 context파일들에는 createContext 를 가져와서 전역상태를 만들어준다.
- createContext()의 인자값으론 초기값을 넣어준다.
- 상태 공유를 위해 다른 컴포넌트를 감싸는 컴포넌트를 만든다고 보면 쉽다.
<ThemeContext></ThemeContext> <UserContext></UserContext> 가 만들어진거다.
// ThemeContext.js
import { createContext } from 'react'
export const ThemeContext = createContext(null);
// UserContext.js
import { createContext } from "react";
export const UserContext = createContext(null)
2. 위에서 만든 context 컴포넌트를 가져와서 전역 상태를 공유할 컴포넌트들을 감싸준다.
Context 객체 안에는 Provider라는 컴포넌트가 들어있다.
궁금해서 Mycontext.Provider 를 출력해보니 아래와 같이 _context를 가지고 있는 객체가 떨어진다.
createContext()의 인자로 넣어준 초기값 ("default value")도 가지고 있다.
import { createContext } from "react";
import GrandParent from "./components/GrandParent";
export const Mycontext = createContext("default value");
function App() {
console.log(Mycontext.Provider);
return (
<Mycontext.Provider value="my context">
<GrandParent />
</Mycontext.Provider>
);
}
export default App;
이 각 컨텍스트.Provider를 써줘야 상태 공유가 가능하며, 꼭 value 라는 props로 전역 상태 값을 넘겨야 자식 컴포넌트들에서 해당 값에 바로 접근이 가능하다
import { useState } from "react";
import Page from "./components/Page";
import { ThemeContext } from "./context/ThemeContext";
import { UserContext } from "./context/UserContext";
const App = () => {
const [isDark, setIsDark] = useState(false)
const user = {
idx: 1,
userid: 'yjlee',
level: 2,
}
return (
<UserContext.Provider value={user}>
<ThemeContext.Provider value={{ isDark, setIsDark }} >
<Page />
</ThemeContext.Provider>
</UserContext.Provider>
);
}
export default App;
3. useContext 메소드를 써서 필요한 컴포넌트들만 전역 값을 쏙 빼다가 쓴다.
Page.jsx : 컴포넌트들을 감싸고 있는 Page는 context가 필요없어서 가져오지 않았다!
즉, props를 쓸때는 부모 컴포넌트가 자기자신이 필요 없는데도 자식에게 전달해야할때 props를 당겨왔지만, context를 쓰면 굳이 가져올 필요가 없다.
import Header from "./Header";
import Content from "./Content";
import Footer from "./Footer";
const Page = () => {
return (
<div className="page">
<Header />
<Content />
<Footer />
</div>
);
};
export default Page;
Content.jsx : 이렇게 필요한 컴포넌트만 가져와서 쓴다.
useContext()
useContext() 로 전역 상태 value 에 바로 접근할 수 있다.
인자값으론 가져올 전역상태값, 즉 createContext로 만든 전역상태를 가져와서 넣어줘야한다!
useContext(ThemeContext) 나 useContext(UserContext) 를 출력해보면,
app.js에서 넘긴 value가 그대로 넘어온 걸 확인할 수 있다.
import { useContext } from "react";
import { ThemeContext } from "../context/ThemeContext";
import { UserContext } from "../context/UserContext";
const Content = () => {
const { isDark } = useContext(ThemeContext)
const { userid, level } = useContext(UserContext)
return (
<div className="content"
style={{
backgroundColor: isDark ? 'black' : 'white',
color: isDark ? 'white' : 'black'
}}>
<p>안녕하세요! {userid}님</p>
<p>현재 레벨은 {level} 입니다.</p>
</div>
)
}
export default Content;
Header.jsx, Footer.jsx도 context를 가져왔는데, 개념은 같으니 생략
출처 : https://www.youtube.com/watch?v=LwvXVEHS638&list=PLZ5oZ2KmQEYjwhSxjB_74PoU6pmFzgVMO&index=5
'React' 카테고리의 다른 글
useCallback (for 컴포넌트 최적화 / useMemo의 함수버전) (0) | 2022.05.12 |
---|---|
useMemo (for 컴포넌트 최적화) (0) | 2022.05.12 |
useRef 복습 - 변수관리 (state와는 다르다!) (0) | 2022.05.11 |
useEffect 복습 (0) | 2022.05.10 |
redux-middleware (redux-thunk) (0) | 2022.05.04 |