简体   繁体   English

如何在 ReactJS 中登录页面后重定向/转到用户配置文件

[英]How to Redirect/go to the User Profile after login page in ReactJS

I am trying to Redirect to the User Profile page once the user is logged in with valid username and password一旦用户使用有效的usernamepassword登录,我就会尝试重定向到User Profile页面

But when I click the Login button, it doesn't go to the User Profile (but it changes the url as intended ( http://localhost:3000/instructor/banuka )但是当我单击Login按钮时,它不会转到User Profile (但它会按预期更改url ( http://localhost:3000/instructor/banuka )

It should also display InstructorLoginFormComponent which it doesn't.它还应该显示它没有的InstructorLoginFormComponent When I click nothing happens but all I can see is still there is the login page当我点击什么都没有发生但我能看到的仍然是login页面

This is my InstructorLoginForm.jsx这是我的InstructorLoginForm.jsx

import React, { Component } from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import InstructorProfile from "./instructor-profile";
import InstructorLoginFormComponent from "./instructor-login-form-component";

export default class InstructorLoginForm extends Component {
  constructor(props) {
    super(props);

    this.state = {
      username: "",
      password: ""
    };

    this.onChangeUsername = this.onChangeUsername.bind(this);
    this.onChangePassword = this.onChangePassword.bind(this);
    this.handleOnClick = this.handleOnClick.bind(this);
  }

  onChangeUsername(e) {
    this.setState({
      username: e.target.value
    });
  }

  onChangePassword(e) {
    this.setState({
      password: e.target.value
    });
  }

  handleOnClick(e) {
    e.preventDefault();
    const path = `/instructor/${this.state.username}`;
    this.props.history.push(path);
  }

  render() {
    return (
      <Router>
        <Switch>
          <Route
            exact
            path="/login"
            component={props => (
              <InstructorLoginFormComponent
                {...props}
                username={this.state.username}
                password={this.state.password}
                handleOnClick={this.handleOnClick}
                onChangeUsername={this.onChangeUsername}
                onChangePassword={this.onChangePassword}
              />
            )}
          />
          <Route
            path={"/instructor/:instructorId"}
            component={InstructorProfile}
          />
        </Switch>
      </Router>
    );
  }
}

This is the InstructorLoginFormComponent.jsx这是InstructorLoginFormComponent.jsx

import React, { Component } from "react";
import { Link } from "react-router-dom";

export default class InstructorLoginFormComponent extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div className="container h-100" style={{ marginTop: 100 }}>
        <div className="d-flex justify-content-center h-100">
          <div className="user_card bg-dark">
            <div className="d-flex justify-content-center">              
            </div>
            <div
              className="d-flex justify-content-center form_container"
              style={{ marginTop: 0 }}
            >
              <form>
                <div className="input-group mb-3">
                  <div className="input-group-append">
                    <span className="input-group-text bg-info">
                      <i className="fa fa-user" />
                    </span>
                  </div>
                  <input
                    value={this.props.username}
                    onChange={this.props.onChangeUsername}
                    type="text"
                    name="username"
                    className="form-control input_user"
                    placeholder="username"
                  />
                </div>
                <div className="input-group mb-2">
                  <div className="input-group-append">
                    <span className="input-group-text bg-info">
                      <i className="fa fa-lock" />
                    </span>
                  </div>
                  <input
                    value={this.props.password}
                    onChange={this.props.onChangePassword}
                    type="password"
                    name="password"
                    className="form-control input_user"
                    placeholder="password"
                  />
                </div>
                <div className="form-group">
                  <div className="custom-control custom-checkbox">
                    <input
                      type="checkbox"
                      className="custom-control-input"
                      id="customControlInline"
                    />
                    <label
                      className="custom-control-label"
                      htmlFor="customControlInline"
                      style={{ color: "#ffffff" }}
                    >
                      Remember me
                    </label>
                  </div>
                </div>
              </form>
            </div>

            <div className="d-flex justify-content-center mt-3 login_container">
              <Link
                to={`/instructor/${this.props.username}`}
                type="button"
                className="btn login_btn bg-info"
              >
                Login
              </Link>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

And this is the InstructorProfile.jsx这是InstructorProfile.jsx

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

export default class InstructorProfile extends Component {
  render(){
      return(
          <div>
              <h1>Welcome to the profile</h1>
          </div>
      );
  }
}

Can someone please tell me where I have went wrong and suggest me a good way to redirect after login validation?有人可以告诉我哪里出错了,并建议我在登录验证后重定向的好方法吗?

Resolved As Is按原样解决

The problems you're experiencing are likely related to your router not being configured correctly.您遇到的问题可能与您的路由器配置不正确有关。 If you want your InstructorLoginFormComponent to be rendered on path / , you have to put it inside the route like below.如果您希望InstructorLoginFormComponent在路径/上呈现,则必须将其放入如下所示的路径中。 You cannot just pass the reference to the component since you need to pass it the username, password, etc props.您不能只将引用传递给组件,因为您需要将用户名、密码等属性传递给它。 You should remove it from anywhere else in your render function since you only want it to render when the path is / .您应该从渲染函数中的任何其他地方删除它,因为您只希望它在路径为/时渲染。 I also changed your instructor path to use :id .我还更改了您的讲师路径以使用:id When you want to specify a url parameter, you need to use the syntax /<my_url>:<my_variable_name> .当要指定 url 参数时,需要使用语法/<my_url>:<my_variable_name> It's important to put the / out front of all your paths because it's a relative path if you don't./放在所有路径的前面很重要,因为如果不这样做,它就是一个相对路径。

New Router Component新路由器组件

<Router>
  <Switch>
    <Route exact path="/login" render={props => (
      <InstructorLoginFormComponent
        {...props}
        username = { this.state.username }
        password = { this.state.password }
        handleOnClick = { this.handleOnClick }
        onChangeUsername = { this.onChangeUsername }
        onChangePassword = { this.onChangePassword }
      />
    )} />          
    <Route path={"/instructor/:instructorId"} component={InstructorProfile} />
  </Switch>
</Router>

Updated handleOnClick更新了 handleOnClick

handleOnClick(e) {
  e.preventDefault();
  const path = `/instructor/${this.state.username}`;
  this.props.history.push(path);
}

Updated Login Button更新登录按钮

<Link
  to={`/instructor/${this.props.username}`}
  type="button"
  className="btn login_btn bg-info"
>
Login
</Link>

Recommendation Regarding Login关于登录的建议

It's important to note that you aren't actually checking the username and password against something on the server.需要注意的是,您实际上并没有根据服务器上的内容检查用户名和密码,这一点很重要。 I'm not sure if this is your test code, or if you intend to implement something with REST.我不确定这是否是您的测试代码,或者您是否打算使用 REST 实现某些内容。 However, you should use a button instead of a link that calls a function on click that sends the username and password to the server.但是,您应该使用按钮而不是在单击时调用函数的链接,该函数将用户名和密码发送到服务器。 From there, it would return if the credentials matched and whether the user would be able to login or not.从那里,如果凭据匹配以及用户是否能够登录,它将返回。 Then, you would use然后,你会使用

this.props.history.push(`instructor/${this.state.username}`);

to forward the user to the instructor profile page.将用户转发到教师个人资料页面。 But you would only want to do that after you have checked their credentials.但是,您只会在检查了他们的凭据后才想这样做。 You would not use a Link component to perform those actions.您不会使用Link组件来执行这些操作。 I put an example below.我在下面举了一个例子。

Example login button登录按钮示例

<button
  type="button"
  className="btn login_btn bg-info"
  onClick={this.props.handleOnClick}
>
Login
</button>

New handleOnClick新的 handleOnClick

handleOnClick = async (e) => {
  e.preventDefault();
  //pseudo-code below
  const user = await checkUserCredentialsAndGetUserObject(this.state.username, this.state.password);
  if(user.response === 'success') {
    this.setState({ user });
    this.props.history.push(`/instructor/${this.state.username}`);
  } else {
    flashMessage('The user credentials you entered were incorrect.');
  }
}

Ok, I'm not exactly sure what you're asking, but I think I know where you're going wrong.好吧,我不太确定你在问什么,但我想我知道你哪里错了。

First of all, when you use the exact keyword on a Route, it will literally only show when the url matches.首先,当您使用确切的关键字上的路线,它会从字面上只有当显示的URL匹配。 So if you want the LoginFormComponent to show in addition to another, you need to remove the exact keyword.因此,如果您希望 LoginFormComponent 除另一个之外显示,则需要删除精确关键字。

Next, for dynamically rendering profile pages, you are not following how React Router works.接下来,对于动态渲染配置文件页面,您没有遵循 React Router 的工作原理。

This tutorial gives a good overview: https://tylermcginnis.com/react-router-url-parameters/本教程提供了一个很好的概述: https : //tylermcginnis.com/react-router-url-parameters/

The short of it is, for the Profile page, the path should be简而言之,对于个人资料页面,路径应该是

<Route path='/instructor/:username' component={InstructorProfile} />

Then, in the profile component, set the initial state by accessing the username in the URL with然后,在配置文件组件中,通过访问 URL 中的用户名来设置初始状态

this.state = {
  user: props.match.params.username
}

The question is a little vague, but I think this will help with what you're trying to do.这个问题有点含糊,但我认为这将有助于您尝试做的事情。 Let me know if something is unclear.如果有不清楚的地方,请告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM