title: React hooks app saga use history.push then doesn't render component correctly
body: <p>Thanks for looking this quesion.  I use typescript to write a react hooks login demo.I have some question.
  1. I use <code>history.push('/home')</code> when login success. but the page render a <code>Notification</code>component.
  2. It's a better way to do router jump in login saga? Other way is do it in Login component.when success.use <code>useHistory</code> hook to do it.I prefer the first way to do it. I am a backend programmer new come to write frontend.so i don't know what is the best way.</p>
  
  <p>The <code>services/history.ts</code></p>
  
  <pre class="lang-js prettyprint-override"><code>import { createBrowserHistory } from 'history';
  
  const history = createBrowserHistory();
  
  export default history;
  </code></pre>
  
  <p>My router</p>
  
  <pre class="lang-js prettyprint-override"><code>import React, { Suspense } from 'react';
  import { Route, Switch, Router } from 'react-router-dom';
  import Loading from '@components/Loading';
  import history from '@services/history';
  import routes from './routes';
  
  const renderRoutes = routes.map(({ path, exact, component, key }) =&gt; (
    &lt;Route exact={exact || false} path={path} key={key} component={component} /&gt;
  ));
  
  const Routers: React.FC = () =&gt; (
    &lt;Router history={history}&gt;
      &lt;Suspense fallback={&lt;Loading /&gt;}&gt;
        &lt;Switch&gt;{renderRoutes}&lt;/Switch&gt;
      &lt;/Suspense&gt;
    &lt;/Router&gt;
  );
  
  export default Routers;
  
  // my routes
  import { lazy } from 'react';
  
  const routes = [
    {
      path: '/',
      key: 'login',
      exact: true,
      component: lazy(() =&gt; import('./../views/login')),
    },
    {
      path: '/home',
      key: 'home',
      component: lazy(() =&gt; import('./../views/home')),
    },
  ];
  
  export default routes;
  
  </code></pre>
  
  <p>my login.tsx</p>
  
  <pre class="lang-js prettyprint-override"><code>const Login: React.FC = () =&gt; {
    const [loading, setLoading] = useState(false);
    const antIcon = &lt;LoadingOutlined style={{ fontSize: 24 }} spin /&gt;;
    const dispatch = useDispatch();
  
    const handleSubmit = (values: any) =&gt; {
      setLoading(true);
      const { username, password } = values;
      dispatch(loginRequest(username, password));
    };
  
    return (
      &lt;div className="login-page"&gt;
        &lt;Form name="login" className="login-form" onFinish={handleSubmit}&gt;
          &lt;p className="login-title"&gt; Go React&lt;/p&gt;
          &lt;FormItem
            name="username"
            rules={[
              { required: true, message: 'Please input your Username!' },
              { min: 4, message: 'min length of username is 4' },
              { max: 12, message: 'max length of username is 12' },
            ]}
          &gt;
            &lt;Input
              prefix={&lt;UserOutlined className="site-form-item-icon" /&gt;}
              placeholder="Username"
              size="large"
            /&gt;
          &lt;/FormItem&gt;
  
          &lt;FormItem
            name="password"
            rules={[
              { required: true, message: 'Please input your Password!' },
              { min: 4, message: 'min length of password is 4' },
              { max: 12, message: 'max length of password is 12' },
            ]}
          &gt;
            &lt;Input
              prefix={&lt;LockOutlined className="site-form-item-icon" /&gt;}
              type="password"
              placeholder="Password"
              size="large"
            /&gt;
          &lt;/FormItem&gt;
  
          &lt;FormItem&gt;
            &lt;Button
              htmlType="submit"
              type="primary"
              className="login-button"
              size="large"
            &gt;
              &lt;Spin indicator={antIcon} spinning={loading} /&gt;
              {loading ? ' Logging in' : ' Login'}
            &lt;/Button&gt;
          &lt;/FormItem&gt;
        &lt;/Form&gt;
      &lt;/div&gt;
    );
  };
  
  export default Login;
  </code></pre>
  
  <p>handlesubmit will send a dispatch, the saga will watch this.
  saga.ts</p>
  
  <pre class="lang-js prettyprint-override"><code>import { fork, all, take, call, put, cancel } from 'redux-saga/effects';
  import { message } from 'antd';
  import fetchLogin from '@services/login';
  import TokenStorage from '@utils/storage';
  import ILoginResponseData from '@models/login';
  import UserModel from '@models/user';
  import history from '@services/history';
  import {
    loginFailed,
    loginSuccess,
    LOGIN_REQUEST,
    LOGIN_SUCCESS,
    LOGIN_FAILED,
  } from './action';
  
  function* LoginRequestSaga(username: string, password: string) {
    try {
      const result: ILoginResponseData = yield call(
        fetchLogin,
        username,
        password
      );
      if (result.code === '1') {
        TokenStorage.storeToken(result.token);
        message.success(result.msg);
        history.push('/home');         &lt;-------------I do history jump in here.
        const user = UserModel.getUser(result.token);
        yield put(loginSuccess(user));
      } else {
        message.error(result.msg);
        yield put(loginFailed());
      }
    } catch (err) {
      message.error(err);
      yield put(loginFailed());
    }
  }
  
  function* watchLogin() {
    while (true) {
      const { authData } = yield take(LOGIN_REQUEST);
      const task = yield fork(
        LoginRequestSaga,
        authData.username,
        authData.password
      );
      const action = yield take([LOGIN_SUCCESS, LOGIN_FAILED]);
      if (action.type === LOGIN_SUCCESS) {
        yield cancel(task);
      }
    }
  }
  
  export default function* rootSaga() {
    yield all([watchLogin()]);
  }
  
  </code></pre>
  
  <p>My home component</p>
  
  <pre class="lang-js prettyprint-override"><code>import React from 'react';
  import { useSelector } from 'react-redux';
  import { RootState } from '@store/reducer';
  
  const Home: React.FC = () =&gt; {
    const user = useSelector((state: RootState) =&gt; state.user);
    return &lt;div&gt;Current User:{user.name}&lt;/div&gt;;
  };
  
  export default Home;
  
  </code></pre>
  
  <p>when login success. the page doesn't show correctly component. </p>
  
  <p><a href="https://i.stack.imgur.com/HMtB8.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/HMtB8.png" alt="enter image description here"></a></p>
  
  <pre><code>  "dependencies": {
      "@ant-design/icons": "^4.1.0",
      "@testing-library/jest-dom": "^4.2.4",
      "@testing-library/react": "^9.3.2",
      "@testing-library/user-event": "^7.1.2",
      "@types/history": "^4.7.6",
      "@types/jest": "^24.0.0",
      "@types/jwt-decode": "^2.2.1",
      "@types/node": "^12.0.0",
      "@types/react": "^16.9.0",
      "@types/react-dom": "^16.9.0",
      "@types/react-redux": "^7.1.9",
      "@types/react-router-dom": "^5.1.5",
      "@types/store": "^2.0.2",
      "antd": "^4.2.5",
      "axios": "^0.19.2",
      "history": "^5.0.0",
      "jwt-decode": "^2.2.0",
      "node-sass": "^4.14.1",
      "react": "^16.13.1",
      "react-app-rewire-alias": "^0.1.6",
      "react-app-rewired": "^2.1.6",
      "react-dom": "^16.13.1",
      "react-redux": "^7.2.0",
      "react-router": "^5.2.0",
      "react-router-dom": "^5.2.0",
      "react-scripts": "3.4.1",
      "redux": "^4.0.5",
      "redux-saga": "^1.1.3",
      "typescript": "~3.7.2"
    },
  </code></pre>