例えば、アクセストークンを Redux のストアに保存していて、そのアクセストークンを使って Web API を呼び出したい。
アクセストークンを受け取って Web API を呼び出すアクションおよび ActionCreator は既にあるとする。
Redux のストアで管理しているステートからコンポーネントの Props にアクセストークンを渡すのは、mapStateToProps でやればいい。
Web API を呼び出す ActionCreator を dispatch する部分は、mapDispatchToProps で書きたいところ。
ただ、mapDispatchToProps 内では mapStateToProps で Props にマップした値を取得できない。
気を利かせて、ownProps に渡してくれたらよかったのに。
さて、どうしよう。
救世主は、connect が受け取る 3 番目の引数、mergeProps だった。
mapStateToProps が返したオブジェクトである stateProps、mapDispatchToProps が返したオブジェクトである dispatchProps、
そして ownProps を受け取り、3 つをマージしたオブジェクトを返す。
mergeProps 内なら、mapStateToProps でマップしたアクセストークンが stateProps から取得できるので、
そのアクセストークンを使って Web API を呼び出すアクションが dispatch できる。
こんな感じで。コードは TypeScript。
import React from 'react';
import { Dispatch } from 'redux';
import { connect } from 'react-redux';
import { AppState } from './reducers';
import { callWebApi } from './actions';
interface IndexPageProps {
dispatch: Dispatch;
token: string;
onLoad: () => void;
}
class IndexPage extends React.Component<IndexPageProps> {
componentDidMount() {
this.props.onLoad();
}
render() {
return ();
}
}
function mapStateToProps(
state: AppState,
ownProps: IndexPageProps
): IndexPageProps {
return {
...ownProps,
token: state.login.token,
};
}
function mapDispatchToProps(
dispatch: Dispatch,
ownProps: IndexPageProps
): IndexPageProps {
return {
...ownProps,
dispatch,
};
}
function mergeProps(
stateProps: IndexPageProps,
dispatchProps: IndexPageProps,
ownProps: IndexPageProps
): IndexPageProps {
return {
...ownProps,
...stateProps,
...dispatchProps,
onLoad: () => {
const token = stateProps.token;
const dispatch = dispatchProps.dispatch;
dispatch(callWebAPI(token));
},
};
}
export default connect(
mapStateToProps,
mapDispatchToProps,
mergeProps
)(IndexPage);