Страница входа не отображается с React Router ProtectedRoute - PullRequest
0 голосов
/ 15 марта 2019

У меня есть приложение реакции маршрутизатора:

    export default () => (
  <Router basename={process.env.REACT_APP_BASENAME || ""}>
    <div>
      {routes.map((route, index) => {
        return (
          <PrivateRoute
            key={index}
            path={route.path}
            exact={route.exact}
            component={props => {
              return (
                <route.layout {...props}>
                  <route.component {...props} />
                </route.layout>
              );
            }}
          />
        );
      })}
    </div>
  </Router>
);

, и оно будет отображать различные виды в зависимости от выбранного маршрута.маршруты будут отображаться на основе этого объекта в файле routes.js:

    export default [
        {
    path: "/login",
    layout: DefaultLayout,
    component: LogIn
  },    .....]

Чтобы встроить некоторую аутентификацию, я определил PrivateRoute как:

    const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={(props) => (
    fakeAuth.isAuthenticated === true
      ? <Component {...props} />
      : <Redirect to='/login' />
  )} />
)

однако, когдая установил приложение как использующее PrivateRoute вместо обычного Route (в первом фрагменте), перенаправление не использует объект маршрутов.Как изменить константу PrivateRoute для страницы входа в систему, отражающую мою первоначальную архитектуру React Route?Какова лучшая практика?

Ответы [ 2 ]

0 голосов
/ 16 марта 2019

Я предлагаю изменить ваш личный маршрут следующим образом

const PrivateRoute = ({ component: Component, ...rest }) => fakeAuth.isAuthenticated === true ? (
  <Route {...rest} component={component}
  )} />
) : <Redirect to='/login' />;
0 голосов
/ 15 марта 2019

Ваш код выглядит нормально, но, поскольку вы сказали, что ваш объект routes не распознается реагирующим маршрутизатором, возможно, в этом случае ваши компоненты не определены должным образом.Например, ваши компоненты могут быть определены после объекта создан.В этом случае, когда этот объект будет создан, он будет ссылаться на undefined компонентов.Я однажды сделал эту ошибку, поэтому я просто делюсь тем, что, возможно, пошло не так.

Вот пример:

import ReactDOM from "react-dom";
import React, { Component } from "react";
import {
  BrowserRouter as Router,
  Route,
  Link,
  Redirect,
  withRouter
} from "react-router-dom";

function Public() {
  return <h3>Public</h3>;
}

function Protected() {
  return <h3>You can see protected content</h3>;
}

class Login extends Component {
  state = { redirectToReferrer: false };

  login = () => {
    fakeAuth.authenticate(() => {
      this.setState({ redirectToReferrer: true });
    });
  };

  render() {
    let { from } = this.props.location.state || { from: { pathname: "/" } };
    let { redirectToReferrer } = this.state;

    if (redirectToReferrer) return <Redirect to={from} />;

    return (
      <div>
        <p>You must log in to view the page at {from.pathname}</p>
        <button onClick={this.login}>Log in</button>
      </div>
    );
  }
}

const routes = [
  {
    path: "/public",
    component: Public,
    private: false
  },
  {
    path: "/login",
    component: Login,
    private: false
  },
  {
    path: "/protected",
    component: Protected,
    private: true
  }
];

function AuthExample() {
  return (
    <Router>
      <div>
        <AuthButton />
        <ul>
          <li>
            <Link to="/public">Public Page</Link>
          </li>
          <li>
            <Link to="/protected">Protected Page</Link>
          </li>
        </ul>
        {routes.map((route, index) => {
          if (route.private)
            return (
              <PrivateRoute
                key={index}
                path={route.path}
                exact={route.exact}
                component={props => {
                  return <route.component {...props} />;
                }}
              />
            );

          return (
            <Route
              key={index}
              path={route.path}
              exact={route.exact}
              component={props => {
                return <route.component {...props} />;
              }}
            />
          );
        })}
      </div>
    </Router>
  );
}

const fakeAuth = {
  isAuthenticated: false,
  authenticate(cb) {
    this.isAuthenticated = true;
    setTimeout(cb, 100); // fake async
  },
  signout(cb) {
    this.isAuthenticated = false;
    setTimeout(cb, 100);
  }
};

const AuthButton = withRouter(({ history }) =>
  fakeAuth.isAuthenticated ? (
    <p>
      Welcome!{" "}
      <button
        onClick={() => {
          fakeAuth.signout(() => history.push("/"));
        }}
      >
        Sign out
      </button>
    </p>
  ) : (
    <p>You are not logged in.</p>
  )
);

function PrivateRoute(props) {
  const { component: Component, ...rest } = props;
  return (
    <Route
      {...rest}
      render={props =>
        fakeAuth.isAuthenticated ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: "/login",
              state: { from: props.location }
            }}
          />
        )
      }
    />
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<AuthExample />, rootElement);

Обратите внимание: Public, Protected и Login компонентыопределенный выше объекта routes.Определение их после routes приведет к ошибкам.

...