Я установил все на стороне Redux и вижу каждое действие в Redux Devtool. Работает все идеально. Проблема возникает, когда я хочу отправить действие в React Component. В компоненте входа я хочу отправить действие, дождаться его ответа, а затем в зависимости от ответа перенаправить его на страницу или показать ошибки. Вот мои коды:
userActions. js
import axios from "axios";
import {
LOGIN_USER,
LOGIN_USER_SUCCESS,
LOGIN_USER_FAILED,
} from "./types";
const loginUserRequest = () => {
return {
type: LOGIN_USER,
};
};
const loginUserSuccess = (user) => {
return {
type: LOGIN_USER_SUCCESS,
payload: user,
};
};
const loginUserFailed = (error) => {
return {
type: LOGIN_USER_FAILED,
payload: error,
};
};
export const loginUser = (dataSubmitted) => {
return (dispatch) => {
dispatch(loginUserRequest());
axios
.post("/api/users/login", dataSubmitted)
.then((response) => {
dispatch(loginUserSuccess(response.data));
})
.catch((err) => {
dispatch(loginUserFailed(err));
});
};
};
userReducer. js:
import {
LOGIN_USER,
LOGIN_USER_SUCCESS,
LOGIN_USER_FAILED,
} from "../actions/types";
const initialState = {
loading: false,
user: "",
error: "",
};
export default function (state = initialState, action) {
switch (action.type) {
case LOGIN_USER:
return { ...state, loading: true };
case LOGIN_USER_SUCCESS:
return { ...state, loading: false, user: action.payload, error: "" };
case LOGIN_USER_FAILED:
return { ...state, loading: false, user: "", error: action.payload };
default:
return state;
}
}
Приведенные выше коды отлично работают и делают свою работу. Проблема заключается в следующем коде, в котором я отправляю действие asyn c. После запуска кода я получаю this.props.userData как undefined.
Login. js
import React, { Component } from "react";
import { connect } from "react-redux";
import { Link } from "react-router-dom";
import { loginUser } from "../../actions/userActions";
export class Login extends Component {
state = {
email: "",
password: "",
errors: [],
};
displayErrors = (errors) =>
errors.map((error, i) => (
<div className="alert alert-danger" key={i}>
{error}
</div>
));
handleSubmit = (e) => {
e.preventDefault();
var { email, password } = this.state;
var errors = [];
if (email === "") {
errors.push("Email is required");
}
if (password === "") {
errors.push("Password is required");
}
this.setState({ errors: errors });
//Problem occurs here
this.props.dispatch(loginUser({ email, password }));
if (response.payload.success) {
sessionStorage.setItem("jwt", response.payload.token);
sessionStorage.setItem("userId", response.payload._id);
this.props.history.push("/");
} else {
errors.push("Username and/or Password is not correct");
this.setState({ errors: errors });
}
};
render() {
return (
<form className="form-signin" onSubmit={this.handleSubmit}>
<h1 className="h3 mb-3 font-weight-normal">Sign in</h1>
{this.state.errors.length > 0 && this.displayErrors(this.state.errors)}
<label for="inputEmail" className="sr-only">
Email address
</label>
<input
type="email"
id="inputEmail"
className="form-control"
placeholder="Email address"
value={this.state.email}
onChange={(e) => {
this.setState({ email: e.target.value });
}}
required
autoFocus
/>
<label for="inputPassword" className="sr-only">
Password
</label>
<input
type="password"
id="inputPassword"
className="form-control"
placeholder="Password"
value={this.state.password}
onChange={(e) => {
this.setState({ password: e.target.value });
}}
required
/>
<div className="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me" /> Remember me
</label>
</div>
<button
className="btn btn-lg btn-primary btn-block"
type="submit"
onClick={this.handleSubmit}
>
Sign in
</button>
<Link to="/register">Sign Up</Link>
</form>
);
}
}
function mapStateToProps(state) {
return {
userData: state.user,
};
}
export default connect(mapStateToProps)(Login);