如何使用React Router正确重定向?

时间:2018-04-14 23:50:15

标签: javascript reactjs react-router react-redux

我正在尝试使用React和React Router设置一个简单的身份验证重定向。

以下是我正在使用的重要软件包及其版本:

{
  "react": "^16.3.1",
  "react-dev-utils": "^5.0.1",
  "react-dom": "^16.3.1",
  "react-redux": "^5.0.7",
  "react-router-dom": "^4.3.0-rc.2",
  "redux": "^3.7.2",
}

这就是我要实现的目标:

1. If user is not signed in and     going to /signin -- allow
2. If user is     signed in and     going to /signin -- redirect to /
3. If user is not signed in and not going to /signin -- redirect to /signin
4. If user is     signed in and not going to /signin -- allow

使用以下代码,重定向似乎正在发生 - 我在浏览器中看到了正确的URL。

但是,对于案例user is signed in and is going to /signin,我确实看到浏览器的网址更改为/,但Dashboard组件未呈现。

以下是相关代码:

app.js

import React, { Component } from "react";
import { Fabric } from "office-ui-fabric-react/lib/Fabric";
import { BrowserRouter as Router } from "react-router-dom";
import SmartRoute from "./smart-route";
import Header from "./ui/header";
import Dashboard from "./dashboard";
import SignIn from "./auth/signin";
import styles from "./app.scss";

class App extends Component {
  render() {
    return (
      <Router>
        <Fabric>
          <Header />
          <section className={styles.main}>
            <SmartRoute exact={true} path="/" component={Dashboard} />
            <SmartRoute exact={true} path="/signin" component={SignIn} />
          </section>
        </Fabric>
      </Router>
    );
  }
}

export default App;

智能route.js

import React from "react";
import { Route, Redirect } from "react-router-dom";
import { connect } from "react-redux";

const renderComponent = (props, isAuthenticated, Component) => {
  const path = props.match.path;
  if (path === "/signin" && !isAuthenticated) return <Component {...props} />;
  if (path === "/signin" && isAuthenticated) return <Redirect to="/" />;
  return isAuthenticated ? <Component {...props} /> : <Redirect to="/signin" />;
};

const SmartRoute = ({ component: Component, isAuthenticated, ...rest }) => (
  <Route
    {...rest}
    render={props => renderComponent(props, isAuthenticated, Component)}
  />
);

const mapStateToProps = state => ({
  isAuthenticated: state.session.authUser !== null
});

export default connect(mapStateToProps)(SmartRoute);

dashboard.js

import React from "react";
const Dashboard = () => <section>Dashboard</section>;
export default Dashboard;

1 个答案:

答案 0 :(得分:2)

问题是update blocking。要解决此问题,您应该使用withRouter HOC这样的

import { withRouter } from 'react-router'
//.. 
export default withRouter(connect(mapStateToProps)(SmartRoute))

它发生的原因是redux实现了shouldComponentUpadte方法,它不知道位置的变化(因此不会重新呈现SmartRoute组件)。为了解决这个问题,您可以将位置作为支持传递给SmartRoute(更有​​效但并非总是直截了当)组件,或者将其包装为withRouter(快速且脏,但可能存在性能问题)。阅读文档了解更多in depth discussion