0

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})
    
  }

1 Answer 1

1

Class-based component's setState lifecycle function can take a second argument callback function that is called after the state is updated.

setState

setState(updater, [callback])

It was commonly used to do something simple like log the updated state.

this.setState({ value }, () => console.log('new value', this.state.value);

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

The second parameter to setState() is an optional callback function that will be executed once setState is completed and the component is re-rendered. Generally we recommend using componentDidUpdate() for such logic instead.

In your case with this.setState({ usernameValid, errorMsg }, this.validateForm); the validateForm function reference is passed as a callback and is invoked after state is updated.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.