Add dynamic HTML in React JS?

1.6k views Asked by At

Why is my code not working? I'm creating a registration form and I'm wanting to add an error message if the passwords do not match. Why is it not letting me dynamically add para tag to my html? Adding some more text here as I'm getting a post is mostly code error......

import React from 'react'
import Navbar from './components/Navbar'
import { Link } from 'react-router-dom'
import './Register.css'
import { useState, useRef } from 'react'
import { createUserWithEmailAndPassword } from "firebase/auth";
import { auth } from './firebase'


function Register() {
    const div = useRef(null);
    const handleSubmit = event => {
        if (password == confirmPassword) {
            createUserWithEmailAndPassword(auth, registerEmail, confirmPassword)
                .then((userCredential) => {
                    // Signed in 
                    const user = userCredential.user;
                    // ...
                })
                .catch((error) => {
                    const errorCode = error.code;
                    const errorMessage = error.message;
                    // ..
                });
        }
        else {
            //problem
            var passNotMatch = document.createElement('p');
            passNotMatch.innerHTML = "Passwords do not match, please try again.";
            div.appendChild(passNotMatch);
            event.preventDefault();
        }
    }

    return (
        <>
            <Navbar />
            <div className='signup-div'>
                <div useRef={div}>
                    <h2>Register</h2>
                    <form onSubmit={handleSubmit}>
                        <input className='input input_email' type="email" placeholder='Email Address' value={registerEmail} onChange={e => setRegisterEmail(e.target.value)} required /> <br />
                        <input className='input input_password' type="password" placeholder='Set password' value={password} onChange={e => setPassword(e.target.value)} required /> <br />
                        <input className='input input_password' type="password" placeholder='Confirm password' value={confirmPassword} onChange={e => setConfirmPassword(e.target.value)} required /> <br />
                        <button type='submit' className='register-button'>Register</button>
                        <Link to='/signin'>Already have an account? Sign In</Link>
                    </form>
                </div>
            </div>
        </>
    )
}


1

There are 1 answers

0
David On

You're using React incorrectly. Directly interacting with the DOM is almost never the right approach in React. Instead, "dynamic" markup is conditionally included in the markup based on state values. For example, consider this markup structure:

return (
  <>
    <Navbar />
    <div className='signup-div'>
      <div>
        <!-- the rest of your markup, then... -->
        {showError ? <p>Passwords do not match, please try again.</p> : null}
      </div>
    </div>
  </>
)

Note the conditional inclusion of the <p> element, based on the boolean value of showError. Which means showError is something you'd track in state:

function Register() {
  const [showError, setShowError] = useState(false);
  const handleSubmit = event => {
    //...
  }

  //...
}

Its initial value is set to false, so the <p> won't be shown. Then you just update the state to true to show it:

else {
  //problem
  setShowError(true);
  event.preventDefault();
}

You would also set it back to false wherever you want in your code. Perhaps at the beginning of the handleSubmit function for example.

Overall the concept is that you don't directly manipulate the DOM. Instead, you track the current "state" of things in state values. The rendering is based on the current state, and updates to the state trigger a re-render.