登录 React Redux 应用程序后重定向到主页

Posted

技术标签:

【中文标题】登录 React Redux 应用程序后重定向到主页【英文标题】:Redirect to Home after Login on React Redux Application 【发布时间】:2018-06-25 22:39:43 【问题描述】:

我正在使用 Create-React-App 学习 React Redux

我在 store、reducers、action 等的逻辑上遇到问题。

我有一个简单的登录页面(省略了一些 JSX 以使其更易于阅读)

登录.js

import React,  Component  from "react";
import  connect  from "react-redux";
import * as actions from '../../actions';
import Logo from "../img/image-center.png";
import "./login.css";


class Login extends Component 
  constructor(props)
    super(props);
    this.state = 
      errorMsg : ""
    ;
    this.loginClicked = this.loginClicked.bind(this);   
    console.log("loggedIn:", this.props.login);
  

  loginClicked() 
    try 
      this.props.loginUser(this.refs.email.value, this.refs.password.value)
      .then(() => 
        console.log("thisprops", this.props);        
      );
    
    catch(ex)
      this.state.errorMsg = "Unable to connect to server";
      console.log("error", ex);
    
  

  render() 
    return (

      <div className="login-bg">
        <div className="container signForm">
            <div className="col s12 l6 login-form">
              <p className="center-align">Login to Trade Portal</p>
              <form>
                <div className="row">
                  <div className="input-field">
                    <input id="email" type="email" className="validate" ref="email" />
                    <label htmlFor="email">Email</label>
                  </div>
                </div>
                <div className="row">
                  <div className="input-field">
                    <input id="password" type="password" className="validate" ref="password" />
                    <label htmlFor="password">Password</label>
                  </div>
                </div>
                <div className="row">
                  <button
                    className="btn waves-effect waves-light"
                    type="button"
                    name="action"
                    onClick=this.loginClicked
                    >
                    Submit
                  </button>
                  <a href="/subcontractor" className="register">
                    Register here
                  </a>
                </div>
                <div className="row"><div style=textAlign: "center", color:"red">this.props.login.message</div></div>   

              </form>
            </div>
          </div>
        </div>
      </div>
    );
  



function mapStateToProps(login)
  return  login  ;


export default connect(mapStateToProps, actions)(Login);

如您所见,LoginClick 函数调用了一个使用 connect 派生的 prop loginUser(实际上调用了我的 Action Login 方法)

actions\index.js

import axios from "axios";
import  FETCH_USER, LOGIN_USER, LOGIN_FAILED  from "./types";


export const fetchUser = () => async dispatch => 
  const res = await axios.get("/api/Account/GetUser");
  dispatch( type: FETCH_USER, payload: res.data );
;

export const loginUser = (username, password) => async dispatch => 
    try 
        const res = await axios.post("/api/Account/Login", username: username, password: password, persistant: false );
        const message = res.data ? "" : "Incorrect username or password";
        dispatch( type: LOGIN_USER, payload:  success: res.data, message: message  );
    
    catch(ex)
        console.log("Login Failed:", ex);
        dispatch( type: LOGIN_FAILED, payload:  success: false, message: "Unable to connect to authentication server"  );
    

以上代码调用我的服务器并登录用户,成功后在 loginReducer.js 中读取

import  LOGIN_USER, LOGIN_FAILED  from "../actions/types";

export default function(state = null, action) 
  console.log(action);
  switch (action.type) 
    case LOGIN_USER:      
      return  success: action.payload.success, message: action.payload.message ;
      break;
    case LOGIN_FAILED:
      return  success: false, message: action.payload.message ;
      break;
      default:
    return  success: false, message: "";
  

现在我的问题是在成功登录到主页时如何将用户重定向到哪里以及如何重定向? “/首页”

我希望我可以在某个地方的 Login.js 中做到这一点,因为有一天我可能想要 2 条登录路线(即,如果从标头登录它可能不会重定向到主页,但是从 Login.js 登录时它应该登录到家)。因此我认为这个动作不应该放在 Action 或 Reducer 中。但我不确定如何在 Login.js 中绑定它,所以当登录成功时,重定向

【问题讨论】:

我会在传奇中做到这一点。结帐 redux-saga,我很高兴我在学习 redux 时采用了这种方法。编辑:看起来您标记了 thunk,您也可以在 thunk 中执行此操作。 yes 标记了 thunk 因为我使用 thunk.. 但我很困惑如何在我的 login.js 文件中绑定一个操作以将用户重定向到主页.. 调度后。我可以轻松地在 JSX 中绑定消息,因此如果我更新商店,它会更新消息,但是我如何绑定一个函数,以便当登录状态更新为已登录时,它会在该页面上重定向.. 【参考方案1】:

可能的方法-

1- 登录成功后从 loginClicked 方法重定向(.then 内),像这样:

loginClicked() 
    try 
      this.props.loginUser(this.refs.email.value, this.refs.password.value)
      .then(() => 
          this.props.history.push('/home');       
      );
    
    catch(ex)
      this.state.errorMsg = "Unable to connect to server";
      console.log("error", ex);
    

2- 或者另一个选项是在 render 方法中添加检查,每当存储发生任何更改时,它都会重新渲染组件,如果您发现 success == true 重定向到主页,像这样:

render()

    if(this.props.success)
        return <Redirect to="/home" />

    return (....)


如果您遵循第一种方法,那么您还需要将检查放在componentDidMount 方法中,如果用户想在成功登录后打开登录页面,请重定向到主页。您正在通过 bool success 检查该 bool 值来维护登录会话。

componentDidMount()
   if(this.props.success) 
      this.props.history.push('/home');
   

建议

避免使用字符串引用,根据 DOC

如果你以前使用过 React,你可能熟悉一个更老的 ref 属性为字符串的 API,如“textInput”,以及 DOM 节点作为 this.refs.textInput 访问。我们建议不要这样做,因为 字符串引用有一些问题,被认为是遗留的,并且很可能 在将来的版本之一中删除。如果您当前正在使用 this.refs.textInput 访问 refs,我们推荐回调模式 而是。

【讨论】:

第二种方式更准确更简单。【参考方案2】:

Redux-thunk 将返回您从 thunk 返回的任何内容,这意味着如果您返回一个承诺(您已经在这样做,因为它是一个 async 函数),您可以简单地在 Login.js 中等待它,然后执行重定向。

看起来您可以简单地修改 Login.js 中的 console.log("thisprops", this.props);,这发生在调用 loginUser 以执行重定向之后。

【讨论】:

【参考方案3】:

你可以在反应生命周期中做到这一点。

componentWillReceiveProps(nextProps) 
  if (nextProps.login.success && nexProps.login.success !== this.props.login.success) 
     this.props.history.push('/home');
  
 

【讨论】:

以上是关于登录 React Redux 应用程序后重定向到主页的主要内容,如果未能解决你的问题,请参考以下文章

React+redux-form - 提交后重定向

在 React 中登录/注册后重定向到邀请链接

如何在通过 Redux 操作进行身份验证后重定向用户?

成功登录后推送(重定向)到路由

如何在您的登录 api 的 Json 响应后重定向用户反应本机

React Router - PrivateRoute,登录后重定向到原始目的地