reactjscontact-form

My contact form made with React and PHP return mailSent: false


I'm a designer, and very beginner in coding. I'm creating my portfolio with React.js, and I'm trying to make a contact form using PHP. I'm asking the user to fill his name, email and a message.

I'm working on localhost:3000 (I don't know if that information matters) I have 2 files: contact.js and contact_form_handler.php, both in the same directory.

When I submit the form, I console.log the state, which returns the information the user filled, but the mail remains unsent. Coding is new to me so maybe my question might sound stupid. Do I need an Apache server to run the PHP code? I thought React has its own Node server.

The React code:

import React, { Component } from 'react';
import axios from 'axios';

const API_PATH = 'http://localhost:3000/src/contact_form_handler.php';

class Contact extends Component {
  constructor(props) {
    super(props);
    this.state = {
      name: '',
      email: '',
      message: '',
      mailSent: false,
      error: null
    }
  }

  render() {
    return(
      <div className="contact" id="contact">
        <h2>Contact</h2>
        <div>
          <form action="/contact_form_handler.php">
          <input 
            type="text" id="name" name="name" placeholder="Votre nom"
            value={this.state.name}
            onChange={e => this.setState({ name: e.target.value })}
          />
          <input
            type="email" id="email" name="email" placeholder="Votre email"
            value={this.state.email}
            onChange={e => this.setState({ email: e.target.value })}
          />
          <textarea 
            id="message" name="message" placeholder="Votre message"
            onChange={e => this.setState({ message: e.target.value })}
            value={this.state.message}
          ></textarea>
          <input type="submit" onClick={e => this.handleFormSubmit(e)} value="ENVOYER"/>

          <div>
            {this.state.mailSent &&
              <div>Thank you for contcting us.</div>
            }
          </div>
          </form>
          </div>
      </div>
    )
  }

  handleFormSubmit( event ) {
    event.preventDefault();
    axios({
      method: 'post',
      url: `${API_PATH}`,
      headers: { 'content-type': 'application/json' },
      data: this.state
    })
      .then(result => {
        this.setState({
          mailSent: result.data.sent
        })
      })
      .catch(error => this.setState({ error: error.message }));
    console.log(this.state);
  }

}

export default Contact;

The PHP code:

<?php
header("Access-Control-Allow-Origin: *");
$rest_json = file_get_contents("php://input");
$_POST = json_decode($rest_json, true);

if (empty($_POST['fname']) && empty($_POST['email'])) die();

if ($_POST)
    {

    // set response code - 200 OK

    http_response_code(200);
    $subject = $_POST['name'];
    $to = "blondeau.cyril@gmail.com";
    $from = $_POST['email'];

    // data

    $message = $_POST['name'] . $_POST['message'];

    // Headers

    $headers = "MIME-Version: 1.0\r\n";
    $headers.= "Content-type: text/html; charset=UTF-8\r\n";
    $headers.= "From: <" . $from . ">";
    mail($to, $subject, $message, $headers);

    // echo json_encode( $_POST );

    echojson_encode(array(
        "sent" => true
    ));
    }
  else
    {

    // tell the user about error

    echo json_encode(["sent" => false, "message" => "Something went wrong"]);
    }

?>

Everything seems ok, but the form doesn't work, I don't receive the email when I submit the form.

Thank you for your help.


Solution

  • Network request is async. setState is also async. You can't see immediate state change.

    If you want to actually observe modified state use a callback

      handleFormSubmit( event ) {
        event.preventDefault();
        axios({
          method: 'post',
          url: `${API_PATH}`,
          headers: { 'content-type': 'application/json' },
          data: this.state
        })
          .then(result => {
            this.setState({
              mailSent: result.data.sent
            }, () => console.log(this.state)) // NB! setState accepts callbacks
          })
          .catch(error => this.setState({ error: error.message }));
    
      }