Как заставить мою функцию входа работать с функциональными компонентами React с использованием React-Router (TypeScript)? - PullRequest
0 голосов
/ 01 февраля 2020

Я задал похожий вопрос здесь. Отличие от этого вопроса в том, что этот вопрос решает ту же проблему с функциональными компонентами Reacts, а другой вопрос - как решить ее с помощью компонентов класса React с состояниями и withRouter (пока без ответа).

Чего я хочу добиться, так это создать очень простую страницу входа. Я прочитал и последовал этому уроку на https://reacttraining.com/react-router/web/example/auth-workflow, но я пытался сделать это с помощью собственного кода, но не могу заставить его работать. При нажатии на кнопку входа в систему меня никогда не переходят на страницу входа. Кажется, процесс перенаправления не работает.

Чего мне не хватает?

app.tsx

import * as React from "react";
import SecretPage from "./secretpage";
import Login from "./loginpage";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Redirect
} from "react-router-dom";
import "./styles.css";

export default function Layout() {
  return (
    <Router>
      <Switch>
        <Route path="/login">
          <Login />
        </Route>
        <Route path="/">
          <Redirect to="/login" />;
        </Route>
        <Route path="/secret">
          <SecretPage />
        </Route>
      </Switch>
    </Router>
  );
}

login.tsx

import * as React from "react";
import { MouseEvent, useState } from "react";
import { useLocation } from "react-router";
import { useHistory, Redirect, Route } from "react-router-dom";
import * as H from "history";

function onLogin({
  e,
  setAuthenticated,
  history,
  from,
}: {
  e?: MouseEvent<HTMLInputElement>;
  setAuthenticated: (b: boolean) => void;
  history: H.History;
  from: H.Location;
}) {

 authenticate().then(res => {
    if (res) {
      console.log("Logging in -> secretpage, from: " + JSON.stringify(from));
      setAuthenticated(true);
      history.replace(from);
    }
  });
}

function authenticate(): Promise<boolean> {
  return Promise.resolve(true);
}

export default function Login() {
  const [isAuthenticated, setAuthenticated] = useState(false);
  let history = useHistory();
  let location = useLocation();

  let { from } = location.state || { from: { pathname: "/" } };

  if (isAuthenticated) {
    console.log("Now authenticaed:" + JSON.stringify(location));

    return (
      <Route path="/secret">
        <Redirect to={{
          pathname: "/secret",
          state: { from: location }
        }} />
      </Route>
    )

  }

  return (
    <div className="login">
      <br />
      <input
        type="button"
        value="Log in to secret page"
        onClick={e => onLogin({ e, setAuthenticated, history, from})}
      />
    </div>
  );
}

secretpage.tsx

import * as React from "react";

export default function SecretPage() {
  console.log("Rendering secret page");
  return (
    <div className="secretPage">
      <h1>Welcome to secret page</h1>
    </div>
  );
}

1 Ответ

0 голосов
/ 01 февраля 2020

В вашем login.tsx Redirect не требуется переносить внутри Route компонента. Вы можете найти в примере, который вы приложили при переобучении. Вы могли видеть, что Redirect используется как RenderProp.
Подробнее о реквизитах рендеринга здесь

А также, в вашем app.tsx измените порядок вашего маршрута маршрута с:

<Route path="/">
  <Redirect to="/login" />;
</Route>
<Route path="/secret">
 <SecretPage />
</Route>

до:

<Route path="/secret">
  <SecretPage />
</Route>
<Route path="/">
  <Redirect to="/login" />
</Route>

Когда вы завернули свой код в Switch в app.tsx. это всегда будет первый подобранный маршрут. в вашем случае это всегда /. И у него есть перенаправление. Таким образом, вы перенаправлены логин. когда вы направляетесь на /secret.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...