기존은 컴포넌트의 props를 통한 데이터 전달이 이루어 진다.
하지만 여러 컴포넌트에 거쳐 자주 사용되는 데이터( 예 : 로그인여부, 프로필정보)의 경우 기존방식은 코드가
복잡하고 불편해진다. 이것을 해결하기위한 방법이 바로 Context이다. Context에 대해 알아보자!
Context ?
- 컴포넌트 트리를 통해 부모가 자식을 통해 전달해주는것이 아닌 곧바로 컴포넌트로 데이터 전달한다.
- 코드가 깔끔해지고, 데이터를 한곳에서 관리하기 때문에 디버깅도 유리하다.
언제 context를 사용할까 ??
- 여러개의 component들이 접근해야하는 데이터에 사용
ex ) 로그인여부 , 정보 ui테마 , 현재언어 등 ..
사용하기전에 고려할점
- component와 context가 연동되면 재사용성이 떨어진다.
- 따라서 다른레벨의 많은 컴포넌트가 데이터를 필요로 하는게 아니라면 props를 통한 데이터전달이 낫다.
- 전역으로 여기저기 사용되는 상태가 있고, 컴포넌트 개수가 많다면 Context를 사용하자!
context API
1. context 생성
const Context = React.createContext(기본값);
- 상위레벨에 매칭되는 Provider가 없다면 기본값이 사용된다.
(Provider없이 컴포넌트 테스트시 유리)
2. Context.Provider (제공자)
<Context.Provider value = { ... }>
- value는 Privider 컴포넌트의 하위 컴포넌트에 전달된다.
- value값은 무조건 상태값이 있어야 하는것은 아니고, 함수도 전달할 수 있다.
- value값이 없으면 오류가 발생함을 주의하자.
- 참고로, 하나의 provider컴포넌트 여러개의 provider컴포넌트와 연결될 수 있다.
3. Context.Consumer (소비자)
<Context.Consumer>
{value => /* 컨텍스트의 값에 따라 컴포넌트 렌더링 */}
</Context.Consumer>
- Provider에 의해 제공된 value를 하위컴포넌트들이 사용한다 .
- 이데이터를 소비한다 해서 Consumer이라고 한다.
- consumer 컴포넌트는 Context의 값 변화를 지켜보다가 값이 변경되면 재 렌더링된다.
[ context API 예제]
import React, { createContext } from "react"; // 1번
const UserInfo = createContext({ name: "gary", id: "garyIsFree" }); //2번
const App = () => {
return (
<UserInfo.Provider value={{ name: "Licat", id: "ImLion" }}> // 3번
<HelloLicat />
</UserInfo.Provider>
);
};
const HelloLicat = () => {
return (
<UserInfo.Consumer> //4번
{(value) => (
<div>
<h2>{value.name}</h2>
<strong>{value.id}</strong>
<HelloLicatTwo/>
</div>
)}
</UserInfo.Consumer>
);
};
const HelloLicatTwo = () => {
return (
<UserInfo.Consumer> //4번
{(value) => (
<div>
<h2>{value.name}</h2>
<strong>{value.id}</strong>
</div>
)}
</UserInfo.Consumer>
);
};
export default App;
1. createContext 를 import해준다.
2. createContext로 UserInfo를 생성한다.
3. Provider로 value 값을 하위 컴포넌트에게 전달해준다. (여기서 value는 { name: "Licat", id: "ImLion" } )
4. Consumer가 Provider로부터 값을 받아 사용한다. 즉,value.name = "Licat" 이 될 것이고, value.id = "ImLion" 이 될 것이다.
Context에 있는 값을 Consumer 대신 다른 방법 없을까 ?
- useContext Hook을 사용하면 된다!
- 함수형 컴포넌트에서 Context를 편하게 사용할 수 있다.
useContext Hook 사용법
- 위 방식과 동일하게 createContext로 context를 생성해준다.
- 아래와 같이 useContext를 사용한다.
const { name, id } = useContext(UserInfo);
[예제]
import { useContext, createContext } from "react";
const UserInfo = createContext({ name: "gary", id: "garyIsFree" });
const App = () => {
return (
<HelloLicat/>
);
};
//------- Consumer을 이용한 방식-----------------------------
// const HelloLicat = () => {
// return (
// <UserInfo.Consumer>
// {(value) => (
// <div>
// <input type="text" />
// <h2>{value.name}</h2>
// <strong>{`@ ${value.id}`}</strong>
// </div>
// )}
// </UserInfo.Consumer>
// );
// };
//--------------------------------------------------------------
const HelloLicat = () => {
const { name, id } = useContext(UserInfo);
return (
<div>
<h2>{name}</h2>
<strong>{id}</strong>
<HelloLicatTwo/>
</div>
);
};
const HelloLicatTwo = () => {
const { name, id } = useContext(UserInfo);
return (
<div>
<h2>{name}</h2>
<strong>{id}</strong>
</div>
);
};
export default App;
1. createContext 를 import해준다.
2. createContext로 UserInfo를 생성한다.
3. useContext (UserInfo) 로 value 값을 name과 id에 구조분해 할당 해준다.
그밖에 파일이 분리되었을 경우에도 필요로 하는곳에 import하여 사용할 수 있다.
정리
기존엔 컴포넌트간에 상태를 교류할때는 부모 → 자식 흐름으로 props를 통해 전달해주었다.
하지만 자주 여기저기서 사용된다면 코드가 복잡해지고 불편해진다.
따라서 Context API 를통해 쉽게 상태를 교류할 수 있다.
그밖에
Context를 사용하는 이유와 리덕스를 사용하는 이유는 비슷하다.
리덕스는 상태관리 라이브러리로 Context API 기반으로 만들어져 있으며 마찬가지로 전역 상태관리를 돕는다.
'FE > REACT' 카테고리의 다른 글
[React] 리액트 키에러 | Warning: Each child in a list should have a unique "key" prop 에러 (0) | 2022.07.23 |
---|---|
[React] 리액트에서 axios 사용하기 (0) | 2022.06.20 |
[React - Hook] useRef가 뭘까 ? 어떻게 사용하지 ? (예제) (0) | 2022.06.14 |
[React] SPA(Single Page Application)를 Q&A방식으로 알아보자! (0) | 2022.06.11 |
[React] 자바스크립트 안에 스타일을 선언하는 방법 (CSS-in-JS) (0) | 2022.06.11 |