그럼에도 불구하고

👨‍💻

[React] Context API란? 본문

React/React basics

[React] Context API란?

zenghyun 2023. 4. 10. 10:45

오늘은 Context API에 대해 알아보겠습니다.

 

[ Context ] 

Context는 리액트 컴포넌트 간에 어떠한 값을 공유할 수 있게 해주는 기능입니다. 주로 Context는 전역적으로 필요한 값을 다룰 때 사용하는데, 꼭 전역적인 필요는 없습니다. Context를 단순히 "리액트 컴포넌트에서 Props가 아닌 또 다른 방식으로 컴포넌트 간에 값을 전달하는 방법이다"라고 접근을 하시는 것이 좋습니다.

 

 

[ Context API ] 

React에서 Props와 State는 부모 컴포넌트와 자식 컴포넌트 또는 한 컴포넌트 안에서 데이터를 다루기 위해 사용됩니다. 이 Props와 State를 사용하게 되면 부모 컴포넌트에서 자식 컴포넌트, 즉  위에서 아래, 한쪽으로 데이터가 흐르게 됩니다.

 

 

만약 다른 컴포넌트에서 한쪽으로 흐르고 있는 데이터를 사용하고 싶은 경우 또는 다른 컴포넌트에서 사용하고 있는 데이터를 현재의 데이터 흐름에 넣고 싶은 경우가 발생한다면 어떻게 해야 할까요?

 

 

React에서 데이터는 위에서 아래로 흐르게 되므로 사용하고 싶은 데이터와 이 데이터를 사용할 컴포넌트의 공통 부모 State에 만들고 사용하고자 하는 데이터의 Props를 전달하면 이 문제를 해결할 수 있습니다. 

 

 

하지만 이처럼 컴포넌트 사이에 공유되는 데이터를 위해 매번 부모 컴포넌트를 수정하고 하위 모든 컴포넌트에 데이터를 Props로 전달하는 것은 매우 비효율적입니다. 이와 같은 문제를 해결하기 위해 React에서는 Flux라는 개념을 도입하였고 그에 걸맞은 Context API를 제공하기 시작했습니다. 

 

Context는 부모 컴포넌트로부터 자식 컴포넌트로 전달되는 데이터의 흐름과는 상관없이 전역적인 데이터를 다룰 때 사용합니다. 전역 데이터를 Context에 저장한 후, 데이터가 필요한 컴포넌트에서 해당 데이터를 불러와 사용할 수 있습니다. 

 

 

React에서 Context를 사용하기 위해서는 Context API를 사용해야 하며,  Context의 Provider와 Consumer를 사용해야 합니다.

 

 

Context에 저장된 데이터를 사용하기 위해서는 공통 부모 컴포넌트에 Context의 Provider를 사용하여 데이터를 제공해야 하며, 데이터를 사용하려는 컴포넌트에서 Context의 Consumer를 사용하여 실제로 데이터를 사용합니다.

 

[ Props로만 데이터를 전달하면 발생할 수 있는 문제 ] 

리액트 애플리케이션에서는 일반적으로 컴포넌트에게 데이터를 전달해주어야 할 때 Props를 통해 전달합니다. 그런데 깊게 위치한 컴포넌트에 데이터를 전달해야 하는 경우에는 여러 컴포넌트를 거쳐 연달아서 Props를 설정해주어야 하기 때문에 불편하고 실수할 가능성이 높아집니다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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 <GrandChild value={value} />;
}
 
function GrandChild({ value }) {
  return <Message value={value} />;
}
 
function Message({ value }) {
  return <div>Received: {value}</div>;
}
cs

 

이러한 코드를 Props Drilling이라고 부릅니다. 컴포넌트를 한 두 개 정도 거쳐서 Props를 전달하는 거라면 괜찮지만 이렇게 4개 정도 거쳐서 전달하게 된다면, 너무 불편할 것입니다. 예를 들어서 Message 컴포넌트를 열어서, 이 value 값이 어디서 오는건지 파악하려고 한다면 그 상위 컴포넌트로 타고 또 타고 거슬러 올라가야 하기 때문에 매우 불편합니다. 또는, value라는 네이밍을 message로 변경을 하고 싶어진다면, 통일성을 맞추기 위해서 또 여러 컴포넌트들을 수정해야 하니까 그것도 그것대로 불편할 것 입니다. 

 

[ Context 사용법 ]

Context는 리액트 패키지에서 createContext라는 함수를 불러와서 만들 수 있습니다.

 

1
2
import { createContext } from 'react';
const MyContext = createContext();
cs

 

Context 객체 안에는 Provider라는 컴포넌트가 들어있습니다. 그리고, 그 컴포넌트 간에 공유하고자 하는 값을 value라는 Props로 설정하면 자식 컴포넌트들에서 해당 값에 바로 접근을 할 수 있습니다.

 

1
2
3
4
5
6
7
function App() {
  return (
    <MyContext.Provider value="Hello World">
      <GrandParent />
    </MyContext.Provider>
  );
}
cs

 

이렇게 하면, 원하는 컴포넌트에서 useContext라는 Hook를 사용하여 Context에 넣은 값에 바로 접근할 수 있습니다. 해당 Hook의 인자에는 createContext로 만든 MyContext를 넣습니다. 

 

1
2
3
4
5
6
import { createContext, useContext } from 'react';
 
function Message() {
  const value = useContext(MyContext);
  return <div>Received: {value}</div>;
}
cs

 

전체 코드 

 

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
31
32
33
import { createContext, useContext } from 'react';
const MyContext = createContext();
 
function App() {
  return (
    <MyContext.Provider value="Hello World">
      <GrandParent />
    </MyContext.Provider>
  );
}
 
function GrandParent() {
  return <Parent />;
}
 
function Parent() {
  return <Child />;
}
 
function Child() {
  return <GrandChild />;
}
 
function GrandChild() {
  return <Message />;
}
 
function Message() {
  const value = useContext(MyContext);
  return <div>Received: {value}</div>;
}
 
export default App;
cs

 

 

ref: https://dev-yakuza.posstree.com/ko/react/context-api/

'React > React basics' 카테고리의 다른 글

[React] props의 defaultProps란?  (0) 2023.04.28
[React] useMemo와 useCallback 이란?  (0) 2023.04.14
[React] useReducer란?  (0) 2023.04.08
[React] useEffect란?  (0) 2023.04.07
[React] useRef란?  (0) 2023.04.06
Comments