5-3. ViewSelectorContainer 컴포넌트 만들기
기존의 ViewSelector
컴포넌트를 컨테이너로 만들어주겠습니다.
src/containers/ViewSelectorContainer.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as baseActions from '../modules/base';
import ViewSelector from '../components/ViewSelector';
class ViewSelectorContainer extends Component {
handleSelect = (view) => {
const { BaseActions } = this.props;
BaseActions.setView(view);
}
render() {
const { view } = this.props;
const { handleSelect } = this;
return (
<ViewSelector selected={view} onSelect={handleSelect}/>
);
}
}
// 리덕스에 연결
export default connect(
(state) => ({
view: state.base.get('view')
}),
(dispatch) => ({
// bindActionCreators 는 액션함수들을 자동으로 바인딩해줍니다.
BaseActions: bindActionCreators(baseActions, dispatch)
})
)(ViewSelectorContainer);
컴포넌트를 컨테이너로 만들 때에는, 기존 컴포넌트가 어떤 props 를 필요로 하는지 참조해서 만드세요.
이번 코드에서는 bindActionCreators
라는 함수가 사용되었습니다. 이는 리덕스에 내장되어있는 함수인데요, 이 함수는 액션을 dispatch
하는 과정을 손쉽게 해줍니다.
원래는 mapDispatchToProps
함수를 따로 만들어서, 내부에서
const mapDispatchToProps = (dispatch) => ({
handleSelect: (view) => dispatch(baseActions.setView(view))
})
이런 작업을 해주어야 했었겠죠?
bindActionCreators
를 사용하면 액션함수를 모두 자동으로 설정해줍니다. 지금의 경우에는 base 모듈에 있는 모든 액션함수를 불러와서 이를 dispatch
하는 함수를 만들어서 props 로 BaseActions 라는 객체안에 넣어서 전달해주었습니다.
이 코드는 다음과 동일합니다:
(dispatch) => ({
BaseActions: {
setView: (payload) => dispatch(baseActions.setView(payload)),
changeSearch: (payload) => dispatch(baseActions.changeSearch(payload))
}
})
이렇게 설정한 함수들은, 렌더링 할 때 직접 실행을 해도 되고, 우리가 이번에 작성한 코드처럼, 컴포넌트 안에 여러분의 컨벤션에 따라 함수를 새로 생성해서 호출해주어도 됩니다.
bindActionCreators
는 이번 컴포넌트처럼 다루는 액션의 수가 적을땐 그리 유용하지 않지만, 액션의 수가 많아질땐 매우 유용합니다.
App 에서 불러와서 사용하기
리덕스에 연결 컴포넌트 App
컴포넌트에서 불러와서 렌더링하세요.
src/App.js
import React, { Component } from 'react';
import Header from './components/Header';
import Container from './components/Container';
import { connect } from 'react-redux'
import ViewSelectorContainer from './containers/ViewSelectorContainer';
class App extends Component {
render() {
// 레퍼런스 준비
const { view } = this.props;
return (
<div>
<Header/>
<ViewSelectorContainer/>
{/* view 값에 따라 다른 컨테이너를 보여준다 */}
<Container visible={view==='favorite'}>
{/* FavoriteListContainer */}
</Container>
<Container visible={view==='list'}>
{/* InputContainer */}
{/* ContactListContainer */}
</Container>
{/* ContactModalContainer */}
{/* FloatingButtonContainer */}
</div>
);
}
}
export default connect(
(state) => ({
view: state.base.get('view')
})
)(App);
이 컴포넌트는 이미 리덕스에 연결이 되어있으니, 따로 전달해줄 props 는 없습니다.