react-redux connect를 Custom HOC로 만들기
- react-redux의 connect함수는 리덕스 스토어와 리액트 컴포넌트를 연결해준다. 그래서 각 리액트 컴포넌트에서 바로 스토어로 쉽게 접근할 수 있다.
- 다만 connect함수를 통해서 접근하고 싶은 state나 action creator가 있는 경우
mapStateToProps
나mapDispatchToProps
로 연결해야 한다. 그리고 보통은 각 함수 내에서 연결하고 싶은 state 프로퍼티나 action creator를 특정한다. - 그러다보면 connect가 쓰이는 컴포넌트마다
mapStateToProps
,mapDispatchToProps
가 반복적으로 쓰이면서 코드가 중복될 수 있다.
일반적으로 connect함수가 쓰이는 모습
const mapStateToProps = state => ({ inbox: state.inbox });
const mapDispatchToProps = dispatch => ({
sendMessage: message => dispatch(sendMessage(massage)),
deleteMessage: id => dispatch(deleteMessage(id)),
})
export default connect(mapSateToProps, mapDispatchToProps)(SomeComponent);
- 이 때 connect 함수를 커스터마이즈해서 custom HOC를 만들면 이런 중복을 없앨 수 있는데, 바로 모든 state와 모든 action creator에 연결하는 것이다.
모든 state와 action creator을 연결하는 HOC
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as actions from '@/data/rootActions';
export default function connectStore(WrappedComponent) {
return connect(
state => state,
dispatch => ({ actions: bindActionCreators(actions, dispatch)})
)(WrappedComponent)
}
- 위 코드는 connect함수의 첫 번째 패러미터에 모든 state를 받아 그대로 반환하는 mapStateToProps를 넣은 것과 같고
- 두 번째 패러미터에 actions라는 프로퍼티로 모든 action creator에 접근할 수 있는 mapDispatchToProps를 넣은 것과 같다. 여기서는 dispatch와 자동으로 바인딩해주는 bindActionCreators를 사용했다.
- 여기서 rootActions는 모든 액션 모듈을 모아서 가지고 있는 파일이다.
- 이제 이 connectStore이라는 함수를 export해서 스토어와 연결할 컴포넌트(eg. App.js)에 import한 다음, connectStore로 감싸서 export하면 된다. (eg.
export default connectStore(App)
) - 이 connectStore과 연결한 컴포넌트에서는
props.actions.someAction()
이런 식으로 바로 action creator를 호출하고 실행할 수 있고,props.someState
이런 식으로 state에 바로 접근할 수 있다.