はじめに
初めての投稿。
これから仕事とか、暇な時にコード書いて覚えたこと、些細なことでも時間ができればメモしておこうと思います。
connected-react-routerとは?
リポ:https://github.com/supasate/connected-react-router
A Redux binding for React Router v4(公式より)
ほうほう、ということは何ができる?
今のpath, hashなど、今の状態を簡単に取得できる
import { connect } from 'react-redux'
const Child = ({ pathname, search, hash }) => (
<div>
Child receives
<div>
pathname: {pathname}
</div>
<div>
search: {search}
</div>
<div>
hash: {hash}
</div>
</div>
)
const mapStateToProps = state => ({
pathname: state.router.location.pathname,
search: state.router.location.search,
hash: state.router.location.hash,
})
export default connect(mapStateToProps)(Child)
react-redux の connect を使ったコンポーネントはstate.router.location.pathname
という風に、今のrouterの状態を調べることができる。
画面遷移を簡単に
それに直接store.dispatch
だけではなく、react-redux
、redux-thunk
、redux-saga
で手軽に画面遷移をすることもできる。
with store.dispatch
import { push } from 'connected-react-router'
store.dispatch(push('/path/to/somewhere'))
with react-redux
import { push } from 'connected-react-router'
// in component render:
<div onClick={() => {
/** do something before redirection */
props.push('/home');
}}>login</div>
// connect the action:
export default connect(null, { push })(Component);
in redux-thunk
import { push } from 'connected-react-router'
export const login = (username, password) => (dispatch) => {
/* do something before redirection */
dispatch(push('/home'))
}
in redux-saga
import { push } from 'connected-react-router'
import { put, call } from 'redux-saga/effects'
export function* login(username, password) {
/* do something before redirection */
yield put(push('/home'))
}
他も色んなことができるが、よく使われる部分(タブン)、かつ今回で使いたい機能はこの二つですね。
実際に使ってみよう
以下は自分の練習プロジェクトからのコピペ:
historyとstore
まずは、historyとstoreの生成から。
history.js
import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
export default history;
すごく簡単ですね。
store.js
import { routerMiddleware } from 'connected-react-router'; /*インポート*/
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import { createLogger } from 'redux-logger';
import history from '@/common/js/history';
import createRootReducer from '@/reducer/index';
function configureStore() {
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
createRootReducer(history),
composeEnhancers(applyMiddleware(
routerMiddleware(history), /*Storeに接続*/
createLogger(),
thunk,
)),
);
return store;
}
const store = configureStore();
export default store;
storeを作る時にcreateRootReducer(history)
とrouterMiddleware(history)
を渡せばおk。
createRootReducer
export default history => combineReducers({
router: connectRouter(history),
auth,
post,
});
ConnectedRouterを使おう
最後は、Routerの部分をConnectedRouterにすれば完成!
import React, { Component } from 'react';
import { ConnectedRouter } from 'connected-react-router';
import { Provider } from 'react-redux';
import { Route, Switch } from 'react-router';
import store from '@/common/js/store';
import history from '@/common/js/history';
import UserLoginPage from './container/page/UserLoginPage';
class App extends Component {
render() {
return (
<Provider store={store}>
<ConnectedRouter history={history}>
<Switch>
<Route exact path="/" component={UserLoginPage} />
</Switch>
</ConnectedRouter>
</Provider>
);
}
}
export default App;
使用例:
UserAction.js
import axios from 'axios';
import { push } from 'connected-react-router';
export function userLogin(account, password) {
return (dispatch) => {
axios.post('/api/sessions', { session: { email: account, password } })
.then(({ data }) => {
dispatch({ type: 'LOGIN_SUCCESS', payload: data });
dispatch(push('/page/posts/view'));
});
};
}