DCCW
DCCW

Reputation: 205

Unable to delete value character from input reactjs

I cannot seem to delete the last character of the value I input.

For example: I will type in the input field: "[email protected]" and want to delete it all to rewrite it. I can backspace all of them without a problem, untill I get to the last character. So the input field now has: "s".

p.s. I am using react-bootstrap validation on top of the validation I wrote myself. This problem started when I wrote the conditional of the value field beïng empty in handleChange.

I have deleted all of the other code to hopefully help get a clear picture of what is going on. If I'm missing something please let me know.

The const below have more than just these objects, but for this problem its not relevant. :

const [validation, setValidation] = useState({email: "notActive"}); 
const [messages, setMessages] = useState({ errormessageEmail: '' });
const [account, setAccount] = useState({ createEmail: ""});

useEffect to validate if the email has the right characters

    useEffect(() => {
        if (validation.email === "active") {
            let err = '';
            const emailRegex = new RegExp("[^\\.\\s@:](?:[^\\s@:]*[^\\s@:\\.])?@[^\\.\\s@]+(?:\\.[^\\.\\s@]+)+(?:\\.[^\\.\\s@]+)*");
            if (emailRegex.test(account.createEmail)) {
                err = false;
                setMessages(prevState => ({ ...prevState, errormessageEmail: err }))
                setValidation(prevState => ({ ...prevState, email: true }));
            } else {
                err = <div className="text-start">{translated.errorMail}</div>
                setMessages(prevState => ({ ...prevState, errormessageEmail: err }))
                setValidation(prevState => ({ ...prevState, email: false }));
            }
        }
    }, [account.createEmail, validation.email, translated.errorMail]);

handleChange:

        const handleChange = (e, i) => {
            const { name, value, type } = e.target;
                if (name === 'createEmail') {
                    if (value === '') {
                        setValidation(prevState => ({ ...prevState, email: false }));
                    } else {
                        setAccount(prevState => ({ ...prevState, [name]: value }));
                        setValidation(prevState => ({ ...prevState, email: "active" }));
                    }
                }
        }

inputfield:

                                        <Form.Group as={Row}>
                                            <Form.Control
                                                name="createEmail"
                                                type="email"
                                                className={validation.email === true ? "form-control is-valid" : validation.email === false || validation.email === "active" ? "form-control is-invalid" : null}
                                                placeholder={props.t('login:CreateEmail')}
                                                value={account.createEmail}
                                                onChange={(e) => handleChange(e)}
                                                required />
                                            {messages.errormessageEmail ?
                                                < Alert className="no-margin-bttm nav-button-full" variant="danger">{messages.errormessageEmail}</Alert>
                                                : null}
                                        </Form.Group>

Can anyone please tell me why it's working like this? Thanks in advance!

Upvotes: 0

Views: 9305

Answers (2)

Paddy Hamilton
Paddy Hamilton

Reputation: 157

It looks like in the handleChange when the value === '' you are updating the validation to be false, but you aren't updating the value of the input with the new value (""). so you still have the last previous value, which is 's'.

So you should just move the updating of then setAccount outside of the if so you always update the value of the input.

like this

const handleChange = (e, i) => {
    const { name, value} = e.target;
    if (name === 'createEmail') {
      setAccount(prevState => ({ ...prevState, [name]: value }));
      if (value === '') {
        setValidation(prevState => ({ ...prevState, email: false }));
      } else {
        setValidation(prevState => ({ ...prevState, email: "active" }));
      }
    }
}

or even better use a ternary operator instead of the if else

const handleChange = (e, i) => {
    const { name, value } = e.target;
    if (name === 'createEmail') {
      setAccount(prevState => ({ ...prevState, [name]: value }));
      setValidation(prevState => ({ ...prevState, email: !value ? false: "active"}));

    }
}

Upvotes: 1

Steve
Steve

Reputation: 1615

Your input field has the value account.createEmail. This value was initialized by useState with an empty string. It can later on be changed with the method setAccount.

However, this method is not called in handleChange listener in case that value === ''.

That explains why internal state is not updated and the input field cannot reflect any changes.

Upvotes: 1

Related Questions