来自 Action Creator 的 history.push() 将更改 URL 但不会导航到页面

history.push() from Action Creator will Change URL but will Not Navigate to Page

我有一个登录页面组件,我想在成功登录后从操作创建者 (thunk) 重定向。 它似乎可以工作,但是 URL 正确更改后页面仍保留在登录页面上。

这里我导入了要在action creator中导入的历史:

// helpers/history.js
import { createBrowserHistory } from 'history';

const history = createBrowserHistory();

export default history;

这里是 action creator 的简化版本:

// actions/session.js
import history from '../helpers/history';


export const login = (formData) => {
    return (dispatch) => {
        dispatch({type: LOGIN_REQUEST})
        return fetch("http://localhost:3001/login", {
...
       .then((user) => {
            history.push('/live-rewards')
            dispatch({
                type: LOGIN_REQUEST_SUCCESS
            })
        })
        .catch(err => {
...

这里是组件的缩短版本,用于显示如何调用登录和导入

// containers/LoginForm.js
import React, { Component } from 'react'
import { connect } from "react-redux";
import { Link } from 'react-router-dom'
import { login } from '../actions/session'

class LoginForm extends Component {
...

    fetchOnSubmit = (e) => {
      e.preventDefault()
      this.props.login(this.state)
    }
...
const mapDispatchToProps = dispatch => {
  return {
    login: (credentials) => {
      return dispatch(login(credentials))
    }
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(LoginForm);

此处改为 browserRouter 的实现方式:

// index.js
...
  <React.StrictMode>
    <Provider store={store}>
        <App />
    </Provider>
  </React.StrictMode>
...
// app.js
...
    <Router>
      <Navbar toggle={toggle} />
      <Sidebar isOpen={isOpen} toggle={toggle} />
      <Switch>
        <Route path='/live-rewards' component={Liverewards}/>
        <Route path='/signin' component={Signin}/>
        <Route path='/signup' component={Signup}/>
        <Route path='/' exact component={Home}/>
      </Switch>
    </Router>
...

我建议您完全放弃这个 history 对象,并从 BrowserRouter 上下文中的组件处理导航,而不是通过动作创建者。

LoginForm 可以通过 withRouter 访问上下文 history 道具。它可以通过 mapStateToProps.

传递 isLoggedIn 道具来访问状态中的凭据

LoginFormrender() 方法将包含一个 Redirect 组件,该组件根据 isLoggedIn 道具有条件地呈现,当您 dispatch LOGIN_REQUEST_SUCCESS.


以某种方式从 state 映射到 boolean 道具 isLoggedIn。一个例子:

const mapStateToProps = (state) => ({
  isLoggedIn: !!state.credentials.token
})

条件渲染:

{this.props.isLoggedIn && <Redirect to="/live-rewards" />}

我更喜欢这种方法,因为这意味着如果用户已经登录,则根本无法加载登录页面。