I don't understand this part of the code:
this.setState({ usernameValid, errorMsg }, this.validateForm);
If we are updating usernameValid
, errorMsg
in the state, what does this.validateForm
do? Because we are writing this outside the object of setState
.
My code:
class StandardForm extends Component {
state = {
username: "",
usernameValid: false,
email: "",
emailValid: false,
password: "",
passwordValid: false,
passwordConfirm: "",
passwordConfirmValid: false,
formValid: false,
errorMsg: {},
};
validateForm = () =>{
let { usernameValid, emailValid, passwordValid, passwordConfirmValid} = this.state;
this.setState({
formValid: usernameValid && emailValid && passwordValid && passwordConfirmValid
})
}
validateUsername = () => {
const { username } = this.state;
let usernameValid = true;
let errorMsg = { ...this.state.errorMsg };
if (username.length < 6 || username.length > 16) {
usernameValid = false;
errorMsg.username = "Username should be between 6 and 15 characters";
}
this.setState({ usernameValid, errorMsg }, this.validateForm);
};
validateEmail = () => {
const { email } = this.state;
let emailValid = true;
let errorMsg = { ...this.state.errorMsg };
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
emailValid = false;
errorMsg.email = "Invalid email format";
}
this.setState({ emailValid, errorMsg }, this.validateForm);
};
validatePassword = () =>{
const { password } = this.state;
let passwordValid = true;
let errorMsg = {...this.state.errorMsg}
if(password.length < 8){
let passwordValid = false;
errorMsg.password = "Password should have at least 8 characters"
}
this.state({passwordValid, errorMsg})
}
confirmPassword = () =>{
const { confirmPassword, password } = this.state.confirmPassword
let passwordConfirmValid = true;
let errorMsg = {...this.state.errorMsg}
if(password !== confirmPassword){
let passwordConfirmValid = false;
errorMsg.passwordConfirm = "Password do not match"
}
this.state({passwordConfirmValid, errorMsg})
}
Class-based component's
setState
lifecycle function can take a second argument callback function that is called after the state is updated.setState
It was commonly used to do something simple like log the updated state.
I think generally it should be avoided and if you need to issue any side-effects like validating form data then a regular component lifecycle method should be used. componentDidUpdate handles updated state or props.
From the docs
In your case with
this.setState({ usernameValid, errorMsg }, this.validateForm);
thevalidateForm
function reference is passed as a callback and is invoked after state is updated.