【问题标题】:How to properly redirect with React Router?如何使用 React Router 正确重定向?
【发布时间】:2018-09-25 00:11:16
【问题描述】:

我正在尝试使用 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 的情况,我确实看到浏览器的 URL 更改为 /,但 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;

smart-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;

【问题讨论】:

标签: javascript reactjs react-router react-redux


【解决方案1】:

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

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

它发生的原因是 redux 实现了 shouldComponentUpadte 方法,它不知道位置变化(因此不会重新渲染 SmartRoute 组件)。为了克服这个问题,您可以将位置作为道具传递给 SmartRoute(更高效但并不总是简单)组件,或者用 withRouter 包装它(快速而肮脏,但可能存在性能问题)。阅读文档以获取更多信息in depth discussion

【讨论】:

    猜你喜欢
    • 2017-12-11
    • 2017-02-20
    • 2017-11-14
    • 2019-08-07
    • 2016-09-28
    • 2021-08-19
    • 2020-07-20
    • 2016-06-16
    • 1970-01-01
    相关资源
    最近更新 更多