Use withRouter HOC from react-router

- Provides router props form the context
 - Changed API requires us to use the history.push function
This commit is contained in:
Kimmo Puputti 2017-02-14 20:32:00 +02:00
parent 8292c1b9cd
commit 9d5533d60e
3 changed files with 33 additions and 30 deletions

View file

@ -1,25 +1,24 @@
import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { Link, withRouter } from 'react-router-dom';
import { logout } from '../../ducks/Auth.ducks';
import css from './Topbar.css';
const Topbar = (props, context) => {
const { isAuthenticated, onLogout, user } = props;
const { router } = context;
const Topbar = props => {
const { isAuthenticated, onLogout, user, push: historyPush } = props;
const house = { dangerouslySetInnerHTML: { __html: '🏠' } };
const hamburger = { dangerouslySetInnerHTML: { __html: '🍔' } };
const handleChange = e => {
const value = e.target.value;
router.transitionTo(value);
historyPush(value);
};
const handleLogout = () => {
// Router is passed to the action to enable redirect to home when
// logout succeeds.
onLogout(router);
// History push function is passed to the action to enable
// redirect to home when logout succeeds.
onLogout(historyPush);
};
return (
@ -60,17 +59,21 @@ const Topbar = (props, context) => {
Topbar.defaultProps = { user: null };
const { bool, object, func, any } = PropTypes;
const { bool, object, func } = PropTypes;
Topbar.propTypes = { isAuthenticated: bool.isRequired, user: object, onLogout: func.isRequired };
Topbar.contextTypes = { router: any };
Topbar.propTypes = {
isAuthenticated: bool.isRequired,
user: object,
onLogout: func.isRequired,
// history.push prop from withRouter
push: func.isRequired,
};
const mapStateToProps = state => ({
isAuthenticated: state.Auth.isAuthenticated,
user: state.Auth.user,
});
const mapDispatchToProps = dispatch => ({ onLogout: router => dispatch(logout(router)) });
const mapDispatchToProps = dispatch => ({ onLogout: historyPush => dispatch(logout(historyPush)) });
export default connect(mapStateToProps, mapDispatchToProps)(Topbar);
export default connect(mapStateToProps, mapDispatchToProps)(withRouter(Topbar));

View file

@ -58,7 +58,7 @@ export const login = (email, password) => ({ type: LOGIN_REQUEST, payload: { ema
export const loginSuccess = user => ({ type: LOGIN_SUCCESS, payload: user });
export const loginError = error => ({ type: LOGIN_ERROR, payload: error, error: true });
export const logout = router => ({ type: LOGOUT_REQUEST, payload: { router } });
export const logout = historyPush => ({ type: LOGOUT_REQUEST, payload: { historyPush } });
export const logoutSuccess = () => ({ type: LOGOUT_SUCCESS });
export const logoutError = error => ({ type: LOGOUT_ERROR, payload: error, error: true });
@ -77,11 +77,11 @@ export function* callLogin(action, sdk) {
export function* callLogout(action, sdk) {
const { payload } = action;
const { router } = payload;
const { historyPush } = payload;
try {
yield call(sdk.logout);
yield put(logoutSuccess());
yield call(router.transitionTo, '/');
yield call(historyPush, '/');
} catch (e) {
yield put(logoutError(e));
}

View file

@ -93,28 +93,28 @@ describe('Auth duck', () => {
describe('logout worker', () => {
it('should redirect to root after logout', () => {
const sdk = { logout: jest.fn() };
const router = { transitionTo: jest.fn() };
const action = logout(router);
const historyPush = jest.fn();
const action = logout(historyPush);
const worker = callLogout(action, sdk);
expect(worker.next()).toEqual({ done: false, value: call(sdk.logout) });
expect(worker.next()).toEqual({ done: false, value: put(logoutSuccess()) });
expect(worker.next()).toEqual({ done: false, value: call(router.transitionTo, '/') });
expect(worker.next()).toEqual({ done: false, value: call(historyPush, '/') });
expect(worker.next().done).toEqual(true);
expect(sdk.logout).not.toHaveBeenCalled();
expect(router.transitionTo).not.toHaveBeenCalled();
expect(historyPush).not.toHaveBeenCalled();
});
it('should not redirect if logout fails', () => {
const sdk = { logout: jest.fn() };
const router = { transitionTo: jest.fn() };
const action = logout(router);
const historyPush = jest.fn();
const action = logout(historyPush);
const worker = callLogout(action, sdk);
expect(worker.next()).toEqual({ done: false, value: call(sdk.logout) });
const error = new Error('Test logout error');
expect(worker.throw(error)).toEqual({ done: false, value: put(logoutError(error)) });
expect(worker.next().done).toEqual(true);
expect(sdk.logout).not.toHaveBeenCalled();
expect(router.transitionTo).not.toHaveBeenCalled();
expect(historyPush).not.toHaveBeenCalled();
});
});
@ -140,9 +140,9 @@ describe('Auth duck', () => {
it('calls logout', () => {
const sdk = { logout: jest.fn() };
const router = { transitionTo: jest.fn() };
const historyPush = jest.fn();
const watcher = watchAuth(sdk);
const logoutAction = logout(router);
const logoutAction = logout(historyPush);
const takeLoginOrLogout = take([LOGIN_REQUEST, LOGOUT_REQUEST]);
const forkLogout = fork(callLogout, logoutAction, sdk);
@ -156,7 +156,7 @@ describe('Auth duck', () => {
expect(watcher.next().value).toEqual(takeLoginOrLogout);
expect(sdk.logout).not.toHaveBeenCalled();
expect(router.transitionTo).not.toHaveBeenCalled();
expect(historyPush).not.toHaveBeenCalled();
});
it('should cancel login if another login comes', () => {
@ -195,10 +195,10 @@ describe('Auth duck', () => {
it('should cancel login if a logout comes', () => {
const sdk = { login: jest.fn(), logout: jest.fn() };
const router = { transitionTo: jest.fn() };
const historyPush = jest.fn();
const watcher = watchAuth(sdk);
const loginAction = login('email', 'password');
const logoutAction = logout(router);
const logoutAction = logout(historyPush);
const task = createMockTask();
const takeLoginOrLogout = take([LOGIN_REQUEST, LOGOUT_REQUEST]);
const forkLogin = fork(callLogin, loginAction, sdk);
@ -226,7 +226,7 @@ describe('Auth duck', () => {
expect(sdk.login).not.toHaveBeenCalled();
expect(sdk.logout).not.toHaveBeenCalled();
expect(router.transitionTo).not.toHaveBeenCalled();
expect(historyPush).not.toHaveBeenCalled();
});
});
});