React-Router-Redux 分派 LOCATION_CHANGE 两次,删除搜索值

React-Router-Redux dispatched LOCATION_CHANGE twice, remove search value

我正在使用与 react-router 4.x 兼容的下一个 (5.0.0-alpha.6) 版本 react-router-redux。 我尝试在 url 上设置参数,同时重定向到下一页。

每次移动到下一页。我意识到它调用了@LOCATION_CHANGE 2 次,in the second time it removes search value。如果我从按钮事件

处理它,它工作正常
import { requireAuth } from '../components/AuthenticatedComponent'
import createHistory from 'history/createBrowserHistory'

const history = createHistory()  

return (
    <ConnectedRouter history={history}>
      <div className="container">
        <Header />
        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/about" component={requireAuth(About)} />
          <Route path="/login" component={Login} />
          <Route component={NotFound} />
        </Switch>
      </div>
    </ConnectedRouter>
  )

AuthenticatedComponent.js

import { push } from 'react-router-redux'

export function requireAuth(Component) {

class AuthenticatedComponent extends React.Component {

    componentWillMount() {
        this.checkAuth(this.props.isAuthenticated);
    }

    componentWillReceiveProps(nextProps) {
        this.checkAuth(nextProps.isAuthenticated);
    }

    checkAuth(isAuthenticated) {
        if (!isAuthenticated) {
            let redirectAfterLogin = this.props.location.pathname;
            this.props.dispatch(push({pathname: "/login", search:`?redirect=${redirectAfterLogin}`}))
        }
    }
 //....

}

我认为你应该在 nextProps 中传递路径名。

class AuthenticatedComponent extends React.Component {

//...

componentWillReceiveProps(nextProps) {
    this.checkAuth(nextProps.isAuthenticated); // <--- call checkAuth
}

checkAuth(isAuthenticated) {
    if (!isAuthenticated) { // <-- isAuthenticated is in nextProps

        // this.props.location.pathame is not in nextProps
        let redirectAfterLogin = this.props.location.pathname;
        this.props.dispatch(push({pathname: "/login", search:`?redirect=${redirectAfterLogin}`}))
    }
 }

//...

class AuthenticatedComponent extends React.Component {

componentWillMount() {
    this.checkAuth(this.props);
}

componentWillReceiveProps(nextProps) {
    this.checkAuth(nextProps); // <--- call checkAuth
}

checkAuth({isAuthenticated, location, dispatch}) {
    if (!isAuthenticated) { 
        let redirectAfterLogin = location.pathname;
        dispatch(push({pathname: "/login", search:`?redirect=${redirectAfterLogin}`}))
    }
 }

//...

react-router-redux is no longer maintained. For your Redux <-> Router syncing needs with React Router 4+. Let's use connected-react-router 库将解决此问题。

以防万一有人遇到类似问题,我正在使用 connected-react-router 库并且 push 导致双重 LOCATION_CHANGE 事件触发。第一个事件将具有正确的搜索参数,而第二个事件将清除它。我的问题是我将 react-router-dom 中的按钮渲染为 Link,如下所示:

<Button
  as={Link}
  basic
  className={styles.basicTealButton}
  onClick={this.handleButtonClick}
>
...

去掉 as={Link} 部分后,一切正常。