【问题标题】:How setting state in React component using React-Router and RouteComponentProps (TypeScript)?如何使用 React-Router 和 RouteComponentProps (TypeScript) 在 React 组件中设置状态?
【发布时间】:2020-05-16 12:18:07
【问题描述】:

我正在学习 React 和 React-Router,并想做一个非常小的登录页面,用户可以在其中登录到密码页面。我正在使用 TypeScript。

我在这里做了一个运行示例:https://codesandbox.io/s/tender-mirzakhani-j1sdc?fontsize=14&hidenavigation=1&theme=dark

我不确定我是否已声明 PropsType 正确以将其应用于 Login 组件。当使用RouteComponentProps 作为属性时,我似乎无法访问组件的状态,因此我可以设置isAuthenticated=true

所以我的问题是如何更新状态以便isAuthenticated 获得 true 的新值?因为 this.state.isAuthenticated 不能从 Login 组件访问,但 this.props.isAuthenticated 是!

我是否必须将状态映射到道具才能获得更新的状态,或者我需要什么才能得到我想要的?

总结一下我在上面示例中的代码:

index.tsx:

import * as React from "react";
import { render } from "react-dom";
import { Layout } from "./App";

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

App.tsx

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

export class Layout extends Component<{}, {}> {
  public render() {
    return (
      <Router>
        <Switch>
          <Route path="/login">
            <Login
              history={null}
              location={null}
              match={null}
              isAuthenticated={false}
            />
          </Route>
          <Route path="/">
            <Redirect to="/login" />;
          </Route>
          <Route path="/secret">
            <SecretPage />
          </Route>
        </Switch>
      </Router>
    );
  }
}

loginpage.tsx:

import * as React from "react";
import { Component, MouseEvent } from "react";
import { RouteComponentProps } from "react-router";
import { withRouter } from "react-router-dom";

interface State {
  isAuthenticated: boolean;
}

type PropsType = RouteComponentProps<any> & {
  isAuthenticated: boolean;
  history: any;
  location: any;
  match: any;
};

export class Login extends Component<PropsType> {
  constructor(props: PropsType, context?: any) {
    super(props, context);
    this.state = { isAuthenticated: false };
  }

  private login(e?: MouseEvent<HTMLInputElement>) {
    console.log("Logging in...");
    this.setState({ isAuthenticated: true });
  }

  public render() {
    console.log("Is authenticated: " + this.props.isAuthenticated);
    if (this.props.isAuthenticated) {
      this.props.history.push("/secret");
    }

    return (
      <div className="login">
        <br />
        <input type="button" value="Log in" onClick={e => this.login(e)} />
      </div>
    );
  }
}

export default withRouter(Login);

secretpage.tsx:

import * as React from "react";
import { Component } from "react";

export class SecretPage extends Component<{}, {}> {
  public render() {
    return (
      <div className="secretPage">
        <h1>Welcome to secret page</h1>
      </div>
    );
  }
}

【问题讨论】:

  • 您可以在此处添加您尝试过的代码吗?这将使问题易于理解
  • 您可以创建一个PrivateRoute 组件,然后让它处理重定向。 react-router 有一个很好的解释 example

标签: reactjs typescript react-router state


【解决方案1】:

注意:这不是对您问题的(直接)答案。如果您只需要一个直接的答案,请忽略这一点。

但我觉得通过在路由周围创建一个简单的包装器来创建 PublicPrivate 路由可能有助于以一种优雅的方式解决您的问题!

关于这个的文章太多了,我在谷歌上找到了这个https://tylermcginnis.com/react-router-protected-routes-authentication/

如果可以,请随意寻找其他简单的教程。

【讨论】:

    【解决方案2】:

    当您将该道具传递给&lt;Login /&gt; 组件时,您似乎将isAuthenticated 设置为false。然后您尝试在&lt;Login /&gt; 组件中使用该状态。如果你将你的状态提升到 &lt;App /&gt; 组件中,然后通过 prop 将其传递给 &lt;Login /&gt; 会更好。

    它可能看起来像这样: 应用程序.tsx

    this.state = { isAuthenticated: false };
    
    private login(e?: MouseEvent<HTMLInputElement>) {
      console.log("Logging in...");
      this.setState({ isAuthenticated: true });
    }
    
    if (this.props.isAuthenticated) {
      this.props.history.push("/secret");
    }
    
    <Login
      history={null}
      location={null}
      match={null}
      isAuthenticated={this.state.isAuthenticated}
      login={this.login}
    />
    
    

    在组件中,不是运行你在其中的函数,而是运行现在传递下来的函数。

    &lt;input type="button" value="Log in" onClick={() =&gt; this.props.login} /&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-12
      • 2018-01-02
      • 1970-01-01
      • 2022-01-19
      • 2020-07-08
      • 1970-01-01
      • 2018-04-06
      相关资源
      最近更新 更多