Context API
는 props를 직접 전달하는 것과 바로 상태 전달이 가능하다.store
를 두고서 상태값들을 서로 공유할 수 있다.
기존의 redux
보다는 사용방법이 훨씬 간단하다.
우선 store
공간을 만든다.(store.js)
context는 createContext
라는 함수를 통해 만든다.
이 함수를 호출하면 Provider와 Consumer라는 컴포넌트들이 반환된다.1
2
3
4
import React from "react";
const Store = React.createContext(null);
export default Store;
Context를 프로젝트에 적용하려면 최상단을 Provider
로 감싸야한다.Provider
내에서 사용할 값은 “value”라고 부른다.
클래스가 생성되었을 때 store가 value를 얻게 된다.
그래서 Provider
에 사용할 함수는 반드시 생성자에 명시해야한다.
생성자에서 state 값 뿐만 아니라 함수도 선언해줘야한다.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
34import React, { Component } from "react";
import AppPresenter from "./AppPresenter";
import Store from "store";
class AppContainer extends Component {
constructor() {
super();
this._changeMessage = () => {
if (this.state.message === 'hello') {
this.setState({
message: 'bye bye',
})
} else {
this.setState({
message: 'hello',
})
}
}
this.state = {
message: 'hi',
changeMessage: this.__changeMessage,
}
}
render(){
return(
<Store.Provider value={this.state}>
<AppPresenter/>
</Store.Provider>
)
}
}
export default AppContainer;
Consumer
는 Context를 사용해야할 때 사용한다.Consumer
는 함수가 아닌 다른 child를 사용하면 안된다.
1 | import React, { Fragment } from "react"; |
context가 여러개 있을 때 Provider를 각각 생성해서 최상위에 여러겹 쌓는게 마음에 걸린다.
자바스크립트 내장함수인 reduce
를 사용하여 깔끔하게 정리할 수 있다.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21import React from 'react';
import { SampleProvider } from './contexts/sample';
import { AnotherProvider } from "./contexts/another";
const AppProvider = ({contexts, children}) => contexts.reduce(
(prev, context) => React.createElement(context, {
children: prev
}),
children
);
const App = () => {
return (
<AppProvider
contexts={[SampleProvider, AnotherProvider]}
>
</AppProvider>
);
};
export default App;
또한 Consumer
에 사용되는 로직을 쉽게 재사용할 수 있도록 HoC를 사용한다면 매우 편리해진다.
1 | import React, { Component, createContext } from 'react'; |
위의 코드를 필요한 하위 컴포넌트에서 가져다 쓰면 된다!!!1
2
3
4
5
6
7
8
9
10
11
12
13
14
import React from 'react';
import {useSample} from "../contexts/sample";
const Receives = ({value}) => {
return (
<div>
현재 설정된 값: {value}
</div>
);
};
export default useSample(Receives);
redux에 비해 훨씬 더 간단하긴 하지만 redux는 단순힌 전역 상태 관리 그이상의 가치가 있다고 한다.
액션기반 앱 상태 업데이트 로직 작성부터, 미들웨어, 강력한 개발자도구까지…Suspense API
또한 요즘 대세라고 한다.
기존에는 리액트는 데이터가 있을 때까지 항상 로딩상태를 가지지만 Suspense API
는 데이터가 있을 때까지 렌더링 되지 않는다고 한다.