jeudi 8 septembre 2022

Is accessing DOM elements in "read-only" mode without Refs a React anti-pattern?

I can't figure out if Refs are necessary if my intention is just to check what's inside of the DOM elements, but not "writing" in them in any way. I have this code in my React application, in which I have a EmailJS form that lets the user send a email to me. I wanted to put a check in the form to make sure that the user would fill each and every input of the form. To do that, the idea was to access the form stored in the DOM to check whether it was filled or not:

Contacts.js

// import statements

export default function Contacts() 
{
    let confirmation;

    const [toSend, setToSend] = useState({
        from_name: '',
        to_name: '',
        message: '',
        reply_to: '',
        confirm: null
    });

    const validateAndSend = () =>
    {
        let isValid = true;
        let stop = false;

        const elementList = document.querySelectorAll("input"); 
        elementList.forEach(  /* Controllo se sono stati compilati tutti i campi del form */
            (e) => {
                if (e.value === ("") && stop === false)  /* Stop è per stampare solo un alert in caso di più campi vuoti */
              {
                alert("You must fill every field of the form!");
                isValid = false;
                stop = true;
              }
            }
        );

        if (isValid === true)
        {
            send(   
                'service_ID',  /* SERVICE ID del servizio su EmailJS.com */
                'template_ID',  /* TEMPLATE ID del template in uso su EmailJS.com */
                toSend,
                'USER ID') /*  USER ID su EmailJS.com */ 
            .then( (response) => {
                console.log("EmailJS server response:", response.status, response.text);
            })
            .catch( (err) => {
                console.log('Error sending email: ', err);
            });

            confirmation = (<p id="confirm_message">Email sent successfully to website's administrator. You will be contacted at the email address you've just provided.</p>) ;
            setToSend((prevState) => { return {...prevState, confirm: true }});
        };

    };

    const handleChange = (e) =>
    {
        setToSend({ ...toSend, [e.target.name]: e.target.value })
    };


    return (
        <div className="Contacts">
            <NavBar />
            <h1>Contact us!</h1>
            { confirmation }
            <form id="contacts-form" onSubmit={(event) => { event.preventDefault(); } }>
                <input type="text" name="from_name" placeholder="from name" value={toSend.from_name} onChange={handleChange} />
                <input type="text" name="to_name" placeholder="to name" value={toSend.to_name} onChange={handleChange} />
                <input type="text" name="message" placeholder="Your message" value={toSend.message} onChange={handleChange} />
                <input type="text" name="reply_to" placeholder="Your email" value={toSend.reply_to} onChange={handleChange} />

                <button type='submit' onClick={ validateAndSend }>Send</button>
            </form>
            <CustomFooter position="stay_fixed" />
        </div>
    );
}

So, the main question is: do I really need to call useRef and access the form with it even tho I don't have any intention to manually edit the DOM ?

Side problem: after the form is submitted, the paragraph stored in { confirmation } does not get displayed.

Aucun commentaire:

Enregistrer un commentaire