1

I am trying to convert HTML, CSS and JS component to react. I did quite easily with HTML and CSS but having problem with JS. I tried with react-helmet but get an error

Cannot read property 'addEventListener' of null

react.js file:

import React,{ Component }from 'react'
import { Helmet } from 'react-helmet'
import './ContactForm.css'

export default class ContactForm extends Component {
    

    render() {
        return (
            <>
                <section>
                    <div className="container">
                        <form action="https://formsubmit.co/[email protected]" method="POST" id="my-form"> 
                                <div className="form-group">
                                    <label for="firstName"> First Name</label>
                                    <input type="text" id="firstName" name="firstName" />
                                </div>
    
                                <div className="form-group">
                                    <label for="latsName">Last Name</label>
                                    <input type="text" id="lastName" name="lastName" />
                                </div>
    
                                <div className="form-group">
                                    <label for="email">Email</label>
                                    <input type="email" id="email" name="email" />
                                </div>
    
                                <div className="form-group">
                                    <label for="massage">Massage</label>
                                    <textarea name="massage" id="massage" cols="30" rows="10"></textarea>
                                </div>
                                <button type="submit">Submit</button>
                        </form>   
                    </div>
                    <div id="status"></div>
                </section>
                <Helmet>
                    <script src="./main.js"></script>
                </Helmet>
                
            </>
            
           
        )
    }
}

Original HTML/CSS/JS:

window.addEventListener("DOMContentLoaded", function () {
  // get the form elements defined in your form HTML above

  var form = document.getElementById("my-form");
  // var button = document.getElementById("my-form-button");
  var status = document.getElementById("status");

  // Success and Error functions for after the form is submitted

  function success() {
    form.reset();
    status.classList.add("success");
    status.innerHTML = "Thanks!";
  }

  function error() {
    status.classList.add("error");
    status.innerHTML = "Oops! There was a problem.";
  }

  // handle the form submission event

  form.addEventListener("submit", function (ev) {
    ev.preventDefault();
    var data = new FormData(form);
    ajax(form.method, form.action, data, success, error);
  });
});

// helper function for sending an AJAX request

function ajax(method, url, data, success, error) {
  var xhr = new XMLHttpRequest();
  xhr.open(method, url);
  xhr.setRequestHeader("Accept", "application/json");
  xhr.onreadystatechange = function () {
    if (xhr.readyState !== XMLHttpRequest.DONE) return;
    if (xhr.status === 200) {
      success(xhr.response, xhr.responseType);
    } else {
      error(xhr.status, xhr.response, xhr.responseType);
    }
  };
  xhr.send(data);
}
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
body {
  font-family: "Montserrat";
}
section {
  height: 100vh;
  width: 100%;
  background-color: aliceblue;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}
.container {
  width: 90%;
  max-width: 500px;
  margin: 0 auto;
  padding: 20px;
  box-shadow: 0px 0px 20px #00000010;
  background-color: white;
  border-radius: 8px;
  margin-bottom: 20px;
}
.form-group {
  width: 100%;
  margin-top: 20px;
  font-size: 20px;
}
.form-group input,
.form-group textarea {
  width: 100%;
  padding: 5px;
  font-size: 18px;
  border: 1px solid rgba(128, 128, 128, 0.199);
  margin-top: 5px;
}

textarea {
  resize: vertical;
}
button[type="submit"] {
  width: 100%;
  border: none;
  outline: none;
  padding: 20px;
  font-size: 24px;
  border-radius: 8px;
  font-family: "Montserrat";
  color: rgb(27, 166, 247);
  text-align: center;
  cursor: pointer;
  margin-top: 10px;
  transition: 0.3s ease background-color;
}
button[type="submit"]:hover {
  background-color: rgb(214, 226, 236);
}
#status {
  width: 90%;
  max-width: 500px;
  text-align: center;
  padding: 10px;
  margin: 0 auto;
  border-radius: 8px;
}
#status.success {
  background-color: rgb(211, 250, 153);
  animation: status 4s ease forwards;
}
#status.error {
  background-color: rgb(250, 129, 92);
  color: white;
  animation: status 4s ease forwards;
}
@keyframes status {
  0% {
    opacity: 1;
    pointer-events: all;
  }
  90% {
    opacity: 1;
    pointer-events: all;
  }
  100% {
    opacity: 0;
    pointer-events: none;
  }
}
<section>
  <div class="container">
    <form action="https://formspree.io/mbjzbwaj" method="POST" id="my-form">

      <div class="form-group">
        <label for="firstName"> First Name</label>
        <input type="text" id="firstName" name="firstName">
      </div>

      <div class="form-group">
        <label for="latsName">Last Name</label>
        <input type="text" id="lastName" name="lastName">
      </div>

      <div class="form-group">
        <label for="email">Email</label>
        <input type="email" id="email" name="email">
      </div>

      <div class="form-group">
        <label for="massage">Massage</label>
        <textarea name="massage" id="massage" cols="30" rows="10"></textarea>
      </div>

      <button type="submit">Submit</button>
    </form>
  </div>
  <div id="status"></div>
</section>

you can find the js file in https://codepen.io/Web_Cifar/pen/gOrrPpO I need that plain js file in react.

2 Answers 2

3

React is a javaScript library => you can insert JavaScript code directly into React.

<script src="./main.js"></script>   //--> is HTML's way to import a JS file

In your case, you need to format your JS code to work properly with React.

Example (with functional component and hooks):

import React, { useState } from "react";
import "./ContactForm.css";

export default function ContactForm() {
   const [formData, setFormData] = useState({
    firstName: "",
    lastName: "",
    email: "",
    massage: ""
  });

  const updateFormData = (e) =>
    setFormData({
      ...formData,
      [e.target.name]: e.target.value
    });

  const submitForm = (e) => {
    e.preventDefault();
    console.log(formData);
    fetch("https://formspree.io/mbjzbwaj", {
      method: "POST",
      body: JSON.stringify({ formData }),
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json"
      }
    })
      .then((res) => {
        console.log(res);
      })
      .catch((err) => {
        console.log(err);
      });
  };

  const { firstName, lastName, email, massage } = formData;

  return (
    <section>
      <div className="container">
        <form id="my-form" onSubmit={submitForm}>
          <div className="form-group">
            <label htmlFor="firstName"> First Name</label>
            <input
              type="text"
              id="firstName"
              name="firstName"
              value={firstName}
              onChange={(e) => updateFormData(e)}
            />
          </div>

          <div className="form-group">
            <label htmlFor="lastName">Last Name</label>
            <input
              type="text"
              id="lastName"
              name="lastName"
              value={lastName}
              onChange={(e) => updateFormData(e)}
            />
          </div>

          <div className="form-group">
            <label htmlFor="email">Email</label>
            <input
              type="email"
              id="email"
              name="email"
              value={email}
              onChange={(e) => updateFormData(e)}
            />
          </div>

          <div className="form-group">
            <label htmlFor="massage">Massage</label>
            <textarea
              name="massage"
              id="massage"
              cols="30"
              rows="10"
              value={massage}
              onChange={(e) => updateFormData(e)}
            ></textarea>
          </div>
          <button type="submit">Submit</button>
        </form>
      </div>
     </section>
  );
}

Demo : stackblitz


EDIT

To use Formspree with React you have to use a specific hook and it's very simple ... (documentation here)

First you need to import formspree

npm i @formspree/react

ContactForm.js

import React from 'react';
import { useForm } from '@formspree/react';

export default function ContactForm() {
  const [state, handleSubmit] = useForm('######'); // hash id
  if (state.succeeded) {
    return <div>Sucess!</div>;
  }
  return (
    <form onSubmit={handleSubmit}>
      <div className="form-group">
        <label htmlFor="firstName"> First Name</label>
        <input type="text" id="firstName" name="firstName" />
      </div>

      <div className="form-group">
        <label htmlFor="lastName">Last Name</label>
        <input type="text" id="lastName" name="lastName" />
      </div>

      <div className="form-group">
        <label htmlFor="email">Email</label>
        <input type="email" id="email" name="email" />
      </div>

      <div className="form-group">
        <label htmlFor="massage">Massage</label>
        <textarea name="massage" id="massage" cols="30" rows="10"></textarea>
      </div>
      <button type="submit" disabled={state.submitting}>
        Submit
      </button>
    </form>
  );
}
  • You will find the hash id in "form details", "integration" tab. in your example you had "...formspree.io/mbjzbwaj" (hash id)
Sign up to request clarification or add additional context in comments.

4 Comments

Hey mate thank you, but it doesn't work. Please once try it yourself.
can you try for "formsubmit.co/[email protected]" rather than "formspree.io/[email protected]" . I will also try
Yes, this is the way you would want to do it!
@axtck thank you both. Can you check out my another recent question please, i have been stuck in these for about a week now. stackoverflow.com/questions/66579675/…
1

In React, event handling and other functionality is done a little bit different.

You can link an event with a handler like this:

<button onClick={handleClick}>CLICK</button>

onClick would be the event, and handleClick the handler function.

Above your render function you could make a handler like this:

const handleClick = () => {
  console.log("Clicked!");
  // do some functionality... 
}

You can also access the event by passing (e)

const handleClick = (e) => {
  e.preventDefault(); // prevent the default action
  console.log("Clicked!");
  // do some functionality... 
}

If you want to convert your code to React, I would suggest you try it out like this and checking out the documentation.

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.