티스토리 뷰
React :
Context API란
https://velopert.com/3606 를 참고해서, 조금더 내용을 보강하여 리덕스와의 비교를 통해 느낀점을 보태 정리한 내용입니다.
| 시작하기에 앞서
3월말에 리액트 16.3 이 정식 릴리즈가 되고 기존에 존재하던 Context API 가 새로워졌습니다. 이렇게, 새로워진 Context API 에 대해서, 한번 자세히 다뤄볼것입니다.
| Context의 용도
- 주로, 애플리케이션으로 전역적으로 데이터가 사용되야 할 때 사용됩니다. 기존의 Context API 도 전역적으로 데이터를 관리하는 용도로 사용할 수는 있었지만, 사용성이 조금 불편해서 자주 사용되지는 않았다고 합니다.
- 주로, redux, react-router, styled-components 등이 기존에 이 Context API 를 기반으로 구현이 되어있다고 합니다. Context API 가 이번에, 단순히 그런 라이브러리에서 사용되는 용도가 아니라, 일반적인 용도로도 사용하기 용이하게끔 업그레이드 되었다고 합니다.
| Context 생성
createContext 함수를 호출하면 Provider 와 Consumer 라는 컴포넌트들이 반환됩니다. Provider 는 Context 에서 사용 할 값을 설정할 때 사용되고, Consumer 는 나중에 우리가 설정한 값을 불러와야 할 때 사용됩니다.
참고로, Context 는 여러개를 만들 수가 있습니다. 때문에, 여러개의 Context 를 사용 할 때 이름이 겹치지 않고 쉽게 다루기 위해서 위와 같이 Provider 와 Consumer 앞에 prefix 를 설정해주기도 한다고 합니다.
const { Provider, Consumer: SampleConsumer } = Context;
// Provider 에서 state 를 사용하기 위해서 컴포넌트를 새로 만들어줍니다.
class SampleProvider extends Component {
state = {
value: "기본값입니다"
};
> Provider
현재 컴포넌트의 state 와 actions 객체를 넣은 객체를 만들어서,Provider 의 value 값으로 사용합니다.
const value = { state, actions };
return <Provider value={value}>{this.props.children}</Provider>;
Context 를 프로젝트에 적용하려면, 앱을 Provider 로 감싸주어야합니다. App.js 를 다음과 같이 수정해야합니다.
const App = () => {
return (
<SampleProvider>
<div className="panes">
<LeftPane />
<RightPane />
</div>
</SampleProvider>
);
};
export default App;
이는 리덕스에서 provider로 감싸주는것과 유사한것 같았습니다. 여기서 리덕스의 구현체가 Context API라는것도 느낄수 있었습니다.
> Consumer
아래와 같이, Consumer를 통해 Context 의 값을 가져올수 있습니다.
import React from 'react';
import { SampleConsumer } from '../contexts/sample';
const Receives = () => {
return (
<SampleConsumer>
{
(sample) => (
<div>
현재 설정된 값: { sample.state.value }
</div>
)
}
</SampleConsumer>
);
};
export default Receives;
- 따라서 아래와 같이 활용해 볼 수 있습니다. 기존에 context를 만들때 만들었던, actions 를 통해서 값을 변경할 수 있습니다.이는 리덕스에서의 액션생성함수에 디스패치 해주는 형태와 유사한점을 알수 있었습니다.
- 또한 Context API의 Consumer 역시, Redux에서 HOC 형태인 connect를 사용해 mapStateToProps mapDispatchToProps를 사용해서 액션생성함수를 가져오거나 Redux state를 가져오는 패턴과 유사하다는 점에서 Context API의 패턴을 차용한점도 느낄 수 있었습니다.
import React, { Component } from 'react';
import { SampleConsumer } from '../contexts/sample';
class Sends extends Component {
state = {
input: ''
}
componentDidMount() {
// :: 초기 값 설정
this.setState({
input: this.props.value,
})
}
handleChange = (e) => {
this.setState({ input: e.target.value });
}
handleSubmit = (e) => {
e.preventDefault();
// :: props로 받은 setValue 호출
this.props.setValue(this.state.input);
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<input value={this.state.input} onChange={this.handleChange}/>
<button type="submit">설정</button>
</form>
);
}
}
// :: Consumer 를 사용하여 context 값을 전달해준 컨테이너 컴포넌트
const SendsContainer = () => (
<SampleConsumer>
{
({state, actions}) => (
<Sends
value={state.value}
setValue={actions.setValue}
/>
)
}
</SampleConsumer>
)
// :: Sends 대신에 SendsContainer 를 내보내줌
export default SendsContainer;
'Front end > React' 카테고리의 다른 글
React - svg 파일을 확장성있는 컴포넌트로 만들어서 스타일링 하기 (1) | 2018.09.03 |
---|---|
React- Create React App 에서 mobx 사용하는방법 (+오류해결) (0) | 2018.08.12 |
React- 리액트교과서 8장 학습내역 (확장성을 이용한 React 고차 컴포넌트-HOC) (0) | 2018.07.18 |
React - 웹앱에서 휴대폰으로 찍은 사진 업로드시 이미지 회전해서 나올때 해결방법 (0) | 2018.07.13 |
React - 리액트 앱 배포시 cache 안남게하기 (0) | 2018.07.12 |