问题
This in My SignUp Component, Im trying To send User to Signin Component If Username And Password Is correct.
this is Signup Code Below,
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import Axios from 'axios';
const initianValue = {
username: '',
password: '',
nameError: '',
passError: '',
dataError: '',
};
class SignUp extends Component {
constructor(props) {
super(props);
this.state = initianValue;
this.handleInputChange = this.handleInputChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleInputChange = (e) => {
this.setState({
[e.target.name]: e.target.value,
});
};
validForm() {
let nameError = '';
let passError = '';
let dataError = '';
const user = {
username: this.state.username,
password: this.state.password,
};
if (!this.state.username) {
nameError = 'Enter Name';
}
if (user.username !== '' && user.password !== '') {
Axios.post('http://localhost:9000/checkUser', user)
.then((res) => this.setState({ dataError: res.data }))
.catch((err) => console.log(err));
}
if (!this.state.password) {
passError = 'Enter Password';
}
if (nameError || passError || dataError) {
this.setState({
nameError,
passError,
dataError,
});
return false;
}
return true;
}
handleSubmit = (e) => {
e.preventDefault();
const isvalid = this.validForm();
if (isvalid) {
this.setState(initianValue, () => this.props.history.push('/SignIn'));
}
};
render() {
return (
<div className='Main'>
<span className='create'>Create Account</span>
<div className='SignUp'>
<form onSubmit={this.handleSubmit}>
<div className='form-group'>
<label>Username</label>
<input
type='text'
name='username'
value={this.state.username}
className='form-control'
onChange={this.handleInputChange}
/>
<div className='error'>
{this.state.nameError}
{this.state.dataError}
</div>
<br />
<label>Password</label>
<input
type='password'
name='password'
value={this.state.password}
className='form-control'
onChange={this.handleInputChange}
/>
<div className='error'>{this.state.passError}</div>
<br />
<button type='submit' className='btn btn-primary'>
Sign Up
</button>
</div>
</form>
</div>
<div className='signinForm'>
<label>
Already Have Account <Link to='/Signin'> Sign In </Link>
</label>
</div>
</div>
);
}
}
export default SignUp;
Its Works Perfect If I Put Right username and password but in wrong username / password its also send me to Signin Page and Shows warning in console like this
index.js:1 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
in SignUp (created by Context.Consumer)
i wrap Both Component SignUp And Signin In Router,
this is my server.js file to send data if username and password is correct in database
app.post('/checkUser', function (req, res) {
const name = req.body.username;
const pass = req.body.password;
conn.query(
`SELECT * FROM users WHERE username = (?) AND password = (?) `,
[name, pass],
(err, rows) => {
if (err) throw err;
if (!rows.length) {
res.send('Wrong Data');
}
}
);
});
回答1:
Your validForm
makes an async call. By the time the async call is finished the validForm
function as well as handleSubmit
function execution is already completed. Then the then
block is executed where you are setting state and therefore the error.
Solution: Make validForm
an async function and await for your async call. Also make handleSubmit
function an async and await for validForm
.
Working demo
Code snippet
class SignUp extends Component {
constructor(props) {
super(props);
this.state = initianValue;
this.handleInputChange = this.handleInputChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleInputChange = e => {
this.setState({
[e.target.name]: e.target.value
});
};
async validForm() {
let nameError = "";
let passError = "";
let dataError = "";
const user = {
username: this.state.username,
password: this.state.password
};
if (!this.state.username) {
nameError = "Enter Name";
}
if (user.username !== "" && user.password !== "") {
await Axios.get("https://jsonplaceholder.typicode.com/todos/1", user) //fake api
.then(res => {
dataError = "user already exists"; //provide dynamic error..
//this.setState({ dataError: res.data }); // not required
})
.catch(err => console.log("err", err));
}
if (!this.state.password) {
passError = "Enter Password";
}
if (nameError || passError || dataError) {
this.setState({
nameError,
passError,
dataError
});
return false;
}
return true;
}
handleSubmit = async e => {
e.preventDefault();
const isvalid = await this.validForm();
if (isvalid) {
this.setState(initianValue, () => this.props.history.push("/SignIn"));
}
};
render() {
return (
<div className="Main">
<span className="create">Create Account</span>
<div className="SignUp">
<form onSubmit={this.handleSubmit}>
<div className="form-group">
<label>Username</label>
<input
type="text"
name="username"
value={this.state.username}
className="form-control"
onChange={this.handleInputChange}
/>
<div className="error">
{this.state.nameError}
{this.state.dataError}
</div>
<br />
<label>Password</label>
<input
type="password"
name="password"
value={this.state.password}
className="form-control"
onChange={this.handleInputChange}
/>
<div className="error">{this.state.passError}</div>
<br />
<button type="submit" className="btn btn-primary">
Sign Up
</button>
</div>
</form>
</div>
<div className="signinForm">
<label>
Already Have Account <Link to="/Signin"> Sign In </Link>
</label>
</div>
</div>
);
}
}
回答2:
The issue could be on the handling of the response of the fetch. This is just a quick guess but try to not set the state of dataError and just modify the value of your variable dataError that you declared in this local function instead of the class variable. Does that make sense? when you check in your "if (nameError || passError || dataError)" you are checking for the local variable of your function and not the class which I think is fine but you aren't changing the variable if the response is an error. Second if you change the setState and then check the state.dataError you might not get the updated value refresh yet in the function.
Let me know if that makes sense and if it works.
来源:https://stackoverflow.com/questions/62737500/how-to-send-user-to-next-page-after-form-validation-in-react