reactjschakra-ui

How can I validate React input is not empty and valid email?


Right now the form is allowing empty and non valid email strings to be stored to my firestore.

In regular html input tag i know using required and type=email forces the validation. Is there not something similar using Chakra Ui?

const SubscribeForm = () => {
    const [input, setInput] = useState("");
    const isError = input === ''

    const handleSubmit = (e) => {

        console.log("saved to firestore , input: " + input)
        e.preventDefault();
        saveEmail(input);
        setInput("Thanks for subscribing!");
    };

    const saveEmail = async (input) => {
        try {
            const docRef = await addDoc(collection(db, "sub-emails"), {
                email: input
            });

            console.log("Document written with ID: ", input);
        } catch (e) {
            console.error("Error adding document: " + input, e);
        }
    };

    return (
        <FormControl isRequired >
            <Text paddingBottom="10px" fontSize="14px" color="white" > Get updated when site goes live!</Text>
            <Input
                isRequired
                value={input}
                onChange={(e) => setInput(e.target.value)} fontSize="13px" placeholder="example@gmail.com" bgColor="white" id='email' type='email' />
            <Button
                onClick={handleSubmit}
                mt={4}
                colorScheme='teal'
                type='submit'
            >
                Submit
            </Button>
        </FormControl>
    )
}

export default SubscribeForm

Doesn't seem like the isRequired and type='email' is working


Solution

  • Create a custom function like this:

    const isValidEmail = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/g;
    
    const validateEmail = (e) => {
      if(e.target?.value && e.target.value.match(isValidEmail)){
        showNoValidEmail(false);
        setInput(e.target.value)
      }else{
        showNoValidEmail(true);
      }
    }

    Where showNoValidEmail it's a boolean state and can be used with a custom html message.

    Now, in your handleSubmit you can do this:

    const handleSubmit = (e) => {
            console.log("saved to firestore , input: " + input)
            e.preventDefault();
            if(input && input.length && input.match(isValidEmail)){
              saveEmail(input);
                setInput("Thanks for subscribing!");
            }else{
              //show a error message or something like that
            }
    };