1

I have made a react form, for usernames and passwords, and have a regex form to validate them.

I have a set state, to first set the value, then I pass in a callback to setState to then verify that the username is correct.

onChange={(e) => this.setState({username: e.target.value}, this.usernameValidator(this.state.username))}

I use the setState callback because I know it will be called each time something is changed, I'm not sure if I should call the method separately?

here is my handler

  usernameValidator = (username) =>{
var usernameRegex = /^[a-zA-Z0-9]+([a-zA-Z0-9](_|-| )[a-zA-Z0-9])*[a-zA-Z0-9]+$/;
if(usernameRegex.test(username)){
  this.setState({
    isUsernameCorrect: true
  })
}else{
  this.setState({
    isUsernameCorrect: false
  })
}
  console.log(this.state.isUsernameCorrect)
}

my issue is that, whenever a user types for example 5 characters, which is passable to the regex pattern, and then deletes any number of characters, to an unacceptable number, the regex pattern will still pass.

How come this is happening, I mean onChange, should also check for deletions, and then the handler would validate again?

EDIT:

after comments, saying It's the regex pattern that is the problem i tried, using some console logs, to find the value of the current state, when It's validated

usernameValidator = (username) =>{
var usernameRegex = /^[a-zA-Z0-9]+([a-zA-Z0-9](_|-| )[a-zA-Z0-9])*[a-zA-Z0-9]+$/;
if(usernameRegex.test(username)){
  this.setState({
    isUsernameCorrect: true
  }, console.log('correct'))
}else if(!usernameRegex.test(username)){
  this.setState({
    isUsernameCorrect: false
  }, console.log('not correct'))
}
  console.log(this.state.isUsernameCorrect)
  console.log(username)
}

it always logs, the username, before the next key is typed so for example if the given username is DDD the passed in value will be DD because it gives in the username before the value is changed

8
  • 1
    Your regex is malformed for your purposes - it passes with just two characters: regex101.com Commented Dec 14, 2018 at 20:52
  • 1
    The issue is with your regex. You have three elements to your regex. Your first character has to be either a letter or a number, and you can have one or more of these. Your next capture is more broad, but you can have zero of these. The final capture must be one or more of letter/number. So any two digit password that is letters and/or numbers would pass this regex. What pattern are you trying to force? Commented Dec 14, 2018 at 20:53
  • 1
    I recreated your post here: codesandbox.io/s/llzlxoj7p7 Try creating a more strict regex, and I suspect it'll address your issue Commented Dec 14, 2018 at 20:55
  • 2
    Your onChange code is incorrect. Look at the sandbox that @lux posted to see how to correctly write it. Commented Dec 14, 2018 at 21:10
  • 1
    the problem was, that i passed the other function in as a callback to setState, so the function would not receive the updated state in. Thank you lux for your solution! Commented Dec 14, 2018 at 21:12

1 Answer 1

1

Try adjusting how the callback after setState is invoked. At current, it's invoked immediately rather than as a proper callback; the latter of which is guaranteed to get called after setState has updated the state:

Current

onChange(e) {
  this.setState({
    username: e.target.value
    }, 
    this.usernameValidator(this.state.username)
  )
}

Suggested (https://codesandbox.io/s/llzlxoj7p7)

  onChange(e) {
    this.setState(
      {
        username: e.target.value
      },
      () => this.usernameValidator(this.state.username)
    );
  }

It's also worth taking a second pass at the regex to ensure it's doing exactly what you'd expect. https://regex101.com/ is a great resource for this. It also has a great cheat sheet for reducing the complexity of [a-zA-Z0-9] to something like [\w\d], which is all word and digit characters.

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.