[英]React Redux is ignoring dispatches
I have two redux actions, one action called register
which works, showing the console.log我有两个 redux 操作,一个称为
register
操作有效,显示了 console.log
However logIn
action doesn't show the console.log, so im assuming there is an issue with redux calling the dispatch in the logIn
action.但是
logIn
操作不显示console.log,所以我假设redux 在logIn
操作中调用调度存在问题。
This is not an issue with the reducer, because an action should be able to call the console.log.这不是 reducer 的问题,因为操作应该能够调用 console.log。
I want to know why redux is not calling the dispatch the actions for logIn action.我想知道为什么 redux 没有调用 dispatch the actions for logIn action。 Even if there is an error, i should be getting an error message in
console.log(err.response)
but even that is not rendering on the console tab.即使出现错误,我也应该在
console.log(err.response)
收到错误消息,但即使在控制台选项卡上也没有呈现。
actions/index.js动作/ index.js
import axios from 'axios';
import { history } from '../components/Navbar';
export const SET_USER = "SET_USER";
export const lOG_FAIL = "lOG_FAIL";
export const REG_SUC = "REG_SUCCESS";
export const REG_FAIL = "REG_FAIL";
export const logIn = (user) => {
return (dispatch) => {
axios.post('/api/users/loginUser',{
username: user.username,
password: user.password
}).then( (res) => {
// localStorage.setItem('JWT', res.data.token);
// history.push('/dashboard');
dispatch({type: SET_USER, user});
}).catch((err)=> {
dispatch({type: lOG_FAIL, err});
console.log(err.response.data); // not even showing err console.
console.log('no console log that appears here either') // doesn't show console log
})
}
}
export const register = (user) => {
return (dispatch) => {
axios.post('/api/users/new',{
username: user.username,
password: user.password,
email: user.email
}).then( (res) => {
// console.log('success')
history.push('/signIn');
dispatch({type: REG_SUC, user});
}).catch((err)=> {
dispatch({type: REG_FAIL, err});
console.log(err.response.data); // shows console.log for this though.
})
}
}
reducer减速器
import { SET_USER, REG_SUC, REG_FAIL, lOG_FAIL} from '../actions/';
const initialState = {
authError: null,
isAuthenticated: false,
token: null,
user: [],
getToken: localStorage.getItem('JWT')
}
export default (state = initialState, action) => {
switch (action.type) {
case SET_USER:
return ({
...state,
user:action.user,
token: action.payload,
isAuthenticated: true
});
case lOG_FAIL:
return({
...state,
authError:action.err
});
case REG_SUC:
return({
...state,
user:action.user,
isAuthenticated:true,
});
case REG_FAIL:
return({
...state,
authError:action.err.response.data
});
default:
return state
}
}
signIn component登录组件
class signIn extends Component{
constructor(props){
super(props)
this.state = {
formData:{
username:"",
password: ""
},
loggedEmail:"",
loginError: "",
myToken:"",
userLoggedIn: false,
emailBlank: true,
passwordBlank: true,
emailInvalid: false,
passwordInValid: false,
// token:localStorage.getItem('JWT')
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange = (e) =>{
e.preventDefault();
const { formData } = this.state;
this.setState({
formData: {
...formData,
[e.target.name]: e.target.value
}
});
}
handleSubmit = (e) => {
e.preventDefault();
const {formData} = this.state;
const {username,password} = formData;
this.setState({
username: this.state.username,
password: this.state.password
});
const creds = {
username, password
}
this.props.logIn(creds);
console.log(creds);
}
componentDidMount(){
}
render(){
if( this.props.token){
return(
<Redirect to="/dashboard"/>
);
}
return (
<div style={ {padding: '20px 100px'}}>
<h1>Sign In</h1>
<form onSubmit={this.handleSubmit}>
<TextField
id="outlined-name2"
label="Username"
className=""
style={{width: 560}}
name="username"
value={this.state.username}
onChange={this.handleChange}
margin="normal"
variant="outlined"
/>
<br></br>
<TextField
id="outlined-name"
label="Password"
name="password"
type="password"
style={{width: 560}}
className=""
value={this.state.password}
onChange={this.handleChange}
margin="normal"
variant="outlined"
/>
<br></br>
<Button variant="outlined" color="primary" type="submit">
Log In
</Button>
</form>
</div>
);
}
}
const mapStateToProps = (state) => ({
token: state.user.getToken
})
const mapDispatchToProps = (dispatch) => ({
logIn: (user) => dispatch(logIn(user))
});
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(signIn));
SignUp Component注册组件
import React, { Component } from 'react';
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
import axios from 'axios';
import { connect } from 'react-redux';
import {register} from '../actions/';
import { Redirect, withRouter } from 'react-router-dom';
class signUp extends Component{
constructor(props){
super(props)
this.state = {
formData:{
username:"",
password: "",
passwordConf:"",
email:""
},
passErr: "",
regSuccess: false
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange = (e) =>{
e.preventDefault();
const { formData } = this.state;
this.setState({
formData: {
...formData,
[e.target.name]: e.target.value
}
});
}
handleSubmit = (e) => {
e.preventDefault();
const {formData} = this.state;
const {username, email, password, passwordConf} = formData;
this.setState({
username: this.state.username,
password: this.state.password,
passwordConf: this.state.passwordConf,
email:this.state.email,
});
const creds = {
username, email, password
}
if(password === passwordConf){
this.props.register(creds);
}
else{
this.setState({
passErr: "Passwords Don't Match"
})
}
}
render(){
const {token } = this.props
if(token){
return <Redirect to='/dashboard'/>
}
return (
<div style={ {padding: '20px 100px'}}>
{this.props.error && (
<div style={{color:'red'}}>
{this.props.error}
</div>
)}
{this.state.passErr && (
<div style={{color:'red'}}>
{this.state.passErr}
</div>
)}
<h1>Sign Up</h1>
<form onSubmit={this.handleSubmit}>
<TextField
id="outlined-name"
label="Username"
style={{width: 560}}
name="username"
value={this.state.username}
onChange={this.handleChange}
margin="normal"
variant="outlined"
/>
<br></br>
<TextField
id="outlined-name"
label="Email"
className=""
style={{width: 560}}
name="email"
value={this.state.email}
onChange={this.handleChange}
margin="normal"
variant="outlined"
/>
<br></br>
<TextField
id="outlined-name"
label="Password"
name="password"
type="password"
style={{width: 560}}
className=""
value={this.state.password}
onChange={this.handleChange}
margin="normal"
variant="outlined"
/>
<br></br>
<TextField
id="outlined-name"
label="Confirm Password"
name="passwordConf"
type="password"
style={{width: 560}}
className=""
value={this.state.passwordConf}
onChange={this.handleChange}
margin="normal"
variant="outlined"
/>
<br></br>
<Button variant="outlined" color="primary" type="submit">
Sign Up
</Button>
</form>
</div>
);
}
}
const mapStateToProps = (state) => ({
token: state.user.getToken,
error: state.user.authError
})
const mapDispatchToProps = (dispatch) => ({
register: (user) => dispatch(register(user))
});
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(signUp));
backend后端
router.post('/loginUser', (req, res, next) => {
passport.authenticate('login', (err, user, info) => {
if (err) {
console.log(err);
}
if (info != undefined) {
console.log(info.message);
res.send(info.message);
} else {
req.logIn(user, err => {
models.User.findOne({
where: {
username: req.body.username,
},
}).then(user => {
const token = jwt.sign({ id: user.id }, 'nodeauthsecret');
res.status(200).send({
auth: true,
token: token,
message: 'user found & logged in',
});
});
});
}
})(req, res, next);
});
In this scenario, the login request was posting a 200
okay response when it was failing.在这种情况下,登录请求在失败时发布了
200
OK 响应。 Therefore axios couldn't catch the error.因此 axios 无法捕获错误。 Fixing the response status solved this issue on the backend.
修复响应状态在后端解决了这个问题。
res.status(401).send(info.message);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.