我正在使用Create-React-App
学习React Redux我在存储,减少,行动等逻辑上遇到了麻烦。
我有一个简单的登录页面(省略了一些JSX以使其更易于阅读)
Login.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方法)
动作\ 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: ""};
}
}
现在我的问题是在哪里以及如何重定向用户成功登录主页? &#34; /主页&#34;
我希望我可以在某个地方使用Login.js,因为有一天我可能想要有2条登录路由(即如果从标题登录它可能不会重定向到主页,但是从Login.js登录时它应该登录到家)。因此我不认为这个动作应该在Action或Reducer中。但我不确定如何在Login.js中绑定它,所以登录成功时,重定向
答案 0 :(得分:3)
可能的方式 -
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,我们建议使用回调模式 代替。
答案 1 :(得分:0)
Redux-thunk将返回你从thunk返回的任何内容,这意味着如果你返回一个promise(你已经在做了因为它是async
函数),你可以在Login中等待它.js然后执行重定向。
看起来你可以简单地修改在调用console.log("thisprops", this.props);
来执行重定向后发生的Login.js中的loginUser
。
答案 2 :(得分:0)
您可以在反应生命周期中执行此操作。
componentWillReceiveProps(nextProps) {
if (nextProps.login.success && nexProps.login.success !== this.props.login.success) {
this.props.history.push('/home');
}
}