evans
evans

Reputation: 563

How to get data from the form when clicking?

I have form inside the component:

const MyPopup = ({ name, authenticity_token }) => {
  <form className="new_review" id="new_review" action="/reviews" acceptCharset="UTF-8" method="post">
    <input name="utf8" type="hidden" value="✓" />
    <input type='hidden' name='authenticity_token' value={authenticity_token} />
    <input value="2" type="hidden" name="review[reviewable_id]" id="review_reviewable_id" />
    <Popup
      // ...
      footer={
        <SendButton
          onClick={() => {
            setMessageShown(true);
          }}
        />
      }
      // ...
    >
    <div className="input-group input-group_indent-b_default">
        <label className="input-group__label" name='review[email]'>email</label>
        <input className="input-group__input" name='review[email]' type="email" />
    </div>
  </form>

You need to send the data of this form to the server. Ajax request. How do I get form data when I click on submit?

const SendButton = () => (
  <button
    onClick={e => {
      const data = new FormData(e.target);
    }}
    className="button popup-footer__button"
  >
    Отправить
  </button>
);

const data is empty

Upvotes: 0

Views: 138

Answers (2)

Cat_Enthusiast
Cat_Enthusiast

Reputation: 15688

Try to abstract the submit functionality away from the button itself. Define a handleSubmit() function and pair it with the form's onSubmit handler. Let the button be as simple as possible, you can still have it do whatever visual actions or other functionality, but let the form handle the actual submit functionality.

You can do something like the following to extract the data from the form:

Working Sandbox: https://codesandbox.io/s/hardcore-austin-bhq8m

MyPopup:

import React from "react";
import Popup from "./Popup";

const handleSubmit = e => {
  e.preventDefault();
  const data = new FormData(e.target);
  const dataIterator = Array.from(data);

  const postObject = dataIterator.reduce((obj, [key, value]) => {
    return {
      ...obj,
      [key]: value
    };
  }, {});

  console.log(postObject);
};

const MyPopup = ({ name, authenticity_token }) => {
  return (
    <form
      onSubmit={handleSubmit}
      className="new_review"
      id="new_review"
      action="/reviews"
      acceptCharset="UTF-8"
      method="post"
    >
      <input name="utf8" type="hidden" value="✓" />
      <input
        type="hidden"
        name="authenticity_token"
        value={authenticity_token}
      />
      <input
        value="2"
        type="hidden"
        name="review[reviewable_id]"
        id="review_reviewable_id"
      />
      <div className="input-group input-group_indent-b_default">
        <label className="input-group__label" name="review[email]">
          email
        </label>
        <input
          className="input-group__input"
          name="review[email]"
          type="email"
        />
        <Popup />
      </div>
    </form>
  );
};

export default MyPopup;

Popup

import React from "react";

const Popup = props => {
  return <button type="submit">Submit</button>;
};

export default Popup;

The postObject includes all the data from the form, I'm assuming this is what you want to do your request :)

Upvotes: 1

Sultan H.
Sultan H.

Reputation: 2938

You need to have this:

    onClick={e => {
      const data = new FormData(e.target);
    }}

As onSubmit to your form instead of having it as onClick to the submit button, the button will be responsible for invoking the form's onSubmit callback function, also give the button type='submit':

    onSubmit={e => {
      e.preventDefault();
      const data = new FormData(e.target);
      console.log('works!', data)
    }}

Reproduced:

const MyPopup = ({ name, authenticity_token }) => {
  <form
    className="new_review"
    id="new_review"
    action="/reviews"
    acceptCharset="UTF-8"
    method="post"
    onSubmit={e => {
      e.preventDefault();
      const data = new FormData(e.target);
      console.log('works!', data)
    }}
   >
    <Popup
      // ...
      footer={
        <SendButton
          onClick={() => {
            setMessageShown(true);
          }}
        />
      }
      // ...
    >
  </form>
const SendButton = () => (
  <button
    type='submit'
    className="button popup-footer__button"
  >

Upvotes: 0

Related Questions