0

I have created a form to enter name, email, website and message. After entering the details using submit button I want to reset all the fields. I don't know how to use control component. Please help.. This is how I enter Input fields.

export default ({
noLabels = false,
margin = "",
small = false,
blueButton = false,
buttonLabel = null,
quickContact = false,
subject = "New message from website",
}) => {
 const [name, setName] = useState(
process.env.NODE_ENV === "development" ? "abc" : ""
)
const [email, setEmail] = useState(
process.env.NODE_ENV === "development" ? "[email protected]" : ""
)
const [phone, setPhone] = useState(
  process.env.NODE_ENV === "development" ? "Phone" : ""
)
const [country, setCountry] = useState(
  process.env.NODE_ENV === "development" ? "Country" : ""
)
const [message, setMessage] = useState(
 process.env.NODE_ENV === "development" ? "Message" : ""
)
const [website, setWebsite] = useState(
  process.env.NODE_ENV === "development" ? "abc.io" : ""
)

const handleSubmit = e => {
  e.preventDefault()

var formData = new FormData()
formData.set("name", name)
formData.set("email", email)
formData.set("phone", phone)
formData.set("country", country)
formData.set("message", message)
formData.set("website", website)
formData.set("subject", subject)

api
  .contact(formData)
  .then(res => {
    if (typeof window !== "undefined") {
      const uikit = require("uikit")
      uikit
        .toggle(
          document.getElementById(
            quickContact
              ? "form_success_message_quick"
              : "form_success_message"
          )
        )
        .toggle()
    }
  })
  .catch(error => {
    if (typeof window !== "undefined") {
      const uikit = require("uikit")
      uikit
        .toggle(
          document.getElementById(
            quickContact ? "form_error_message_quick" : 
                    "form_error_message"
          )
        )
        .toggle()
    }
  })
 }

 return (
  <form
  action="/send-mail.php"
  className="uk-form contact_form"
  method="post"
  onSubmit={handleSubmit}
   >
     <div
       className="uk-alert-primary contact-form-success-quick"
     data-uk-alert
     id={
       quickContact ? "form_success_message_quick" : 
              "form_success_message"
    }
    hidden
     >
      <a className="uk-alert-close" data-uk-close></a>
      <p>
        Thank you for contacting us. We will get in touch with you 
         shortly.
    </p>
  </div>

     <div
    className="uk-alert-primary contact-form-error-quick"
    data-uk-alert
    id={quickContact ? "form_error_message_quick" : "form_error_message"}
    hidden>
    <a className="uk-alert-close" data-uk-close></a>
    <p>
      Thank you for contacting us. We will get in touch with you shortly.
    </p>
    </div>
    <div
    className={`uk-grid ${
      small || quickContact ? "uk-grid-small" : "uk-grid-medium"
    }`}
    >
      <div className={quickContact ? "uk-width-1-3@s" : "uk-width-1-2@s"}>
      <InputField
        label="Name *"
        value={name}
        setValue={setName}
        noLabels={noLabels}
        margin={margin}
        small={small}
      />
    </div>

    <div className={quickContact ? "uk-width-1-3@s" : "uk-width-1-2@s"}>
      <InputField
        label="Email *"
        value={email}
        setValue={setEmail}
        noLabels={noLabels}
        margin={margin}
        small={small}
      />
    </div>

    {quickContact && (
      <div className="uk-width-1-3@s">
        <InputField
          label="Website"
          value={website}
          setValue={setWebsite}
          noLabels={noLabels}
          margin={margin}
          small={small}
        />
      </div>
    )}

    {!quickContact && (
      <div className="uk-width-1-2@s">
        <InputField
          label="Phone number *"
          value={phone}
          setValue={setPhone}
          noLabels={noLabels}
          margin={margin}
          small={small}
        />
      </div>
    )}

    {!quickContact && (
      <div className="uk-width-1-2@s">
        <InputField
          label="Website"
          value={website}
          setValue={setWebsite}
          noLabels={noLabels}
          margin={margin}
          small={small}
        />
      </div>
    )}

    <div className="uk-width-1-1">
      <InputField
        label="Message *"
        value={message}
        setValue={setMessage}
        textArea
        noLabels={noLabels}
        margin={margin}
        small={small}
      />
    </div>

    <div className="uk-width-1-1 uk-text-center">
      <button
        type="submit"
        className={`uk-button ${blueButton ? "blue" : "purple"}`}
        value="Submit"
        name="submit"
      >
        {buttonLabel ? buttonLabel : "Submit"}
      </button>
    </div>
  </div>
</form>
)
  }

const InputField = ({
noLabels,
value,
setValue,
label,
 textArea = false,
 margin,
 small,
  }) => {
  <>
  {textArea ? (
    <textarea
      placeholder={label}
      className={`uk-textarea custom-margin-${
        margin ? margin + "-" : ""
      }bottom ${!small && "uk-form-large"}`}
      cols="30"
      rows="6"
      required
      value={value}
      onChange={e => setValue(e.target.value)}
    ></textarea>
    ) : (
    <input
      type="text"
      className={`uk-input custom-margin-${
        margin ? margin + "-" : ""
      }bottom ${!small && "uk-form-large"}`}
      placeholder={label}
      required
      value={value}
      onChange={e => setValue(e.target.value)}
    />
   )}
 </>     

I want to reset this code using "e.target.reset()" if possible. Also the method how to use "setValue" would be great help.

5
  • Have you tried calling "setState"/"state update function" with "initial" state values for them? Commented Oct 13, 2020 at 22:23
  • @DrewReese No please can you it bit more. Commented Oct 13, 2020 at 23:22
  • Something like setValue('') in the submit handler. If you can provide a more complete component example I can likely formulate a resolution. Commented Oct 13, 2020 at 23:25
  • @DrewReese OH yes, I'll.. Pease check my code again in the question. Thank you so much Commented Oct 14, 2020 at 0:18
  • @DrewReese Please help mee.. I really need help to finish this now.. All i need is to reset inputs after clicking submit using this code Commented Oct 14, 2020 at 0:41

2 Answers 2

1
  1. Use a single useState hook to hold the values for the form to make it easier to set them all in a single call.
  2. Don't manipulate the DOM directly—instead use state + React to declare the desired output given the current state.
  3. Refactor multiple conditionals that are addressing the same concern into a single conditional (re: process.env.NODE_ENV)
  4. Pass a callback to the state setter to modify the existing props rather than having to explicitly write the function to modify each input's value manually.
const devValues = {
  name: "abc",
  email: "[email protected]",
  phone: "Phone",
  country: "Country",
  message: "Message",
  website: "abc.io",
}

const defaultValues = {
  name: "",
  email: "",
  phone: "",
  country: "",
  message: "",
  website: "",
}

export default ({
  noLabels = false,
  margin = "",
  small = false,
  blueButton = false,
  buttonLabel = null,
  quickContact = false,
  subject = "New message from website",
}) => {
  const [message, setMessage] = useState(null)
  const [inputValues, setInputValues] = useState(
    process.env.NODE_ENV === "development" ? devValues : defaultValues
  )

  const handleSubmit = (e) => {
    e.preventDefault()

    var formData = new FormData()
    Object.entries(inputValues).forEach(([key, value]) => {
      formData.set(key, value)
    })

    api
      .contact(formData)
      .then((res) => {
        setMessage(
          quickContact ? "form_success_message_quick" : "form_success_message"
        )

        // clear the input values here
        setInputValues(defaultValues)
      })
      .catch((error) => {
        setMessage(
          quickContact ? "form_error_message_quick" : "form_error_message"
        )
      })
  }

  return (
    <form
      action="/send-mail.php"
      className="uk-form contact_form"
      method="post"
      onSubmit={handleSubmit}
    >
      {message && (
        <div
          className={
            message.startsWith("form_success_message")
              ? "uk-alert-primary contact-form-success-quick"
              : "uk-alert-primary contact-form-error-quick"
          }
          data-uk-alert
        >
          <a className="uk-alert-close" data-uk-close></a>
          <p>
            Thank you for contacting us. We will get in touch with you shortly.
          </p>
        </div>
      )}

      <div
        className={`uk-grid ${
          small || quickContact ? "uk-grid-small" : "uk-grid-medium"
        }`}
      >
        <div className={quickContact ? "uk-width-1-3@s" : "uk-width-1-2@s"}>
          <InputField
            label="Name *"
            name="name"
            value={inputValues.name}
            setValue={setInputValues}
            noLabels={noLabels}
            margin={margin}
            small={small}
          />
        </div>

        <div className={quickContact ? "uk-width-1-3@s" : "uk-width-1-2@s"}>
          <InputField
            label="Email *"
            name="email"
            value={inputValues.email}
            setValue={setInputValues}
            noLabels={noLabels}
            margin={margin}
            small={small}
          />
        </div>

        {quickContact && (
          <div className="uk-width-1-3@s">
            <InputField
              label="Website"
              name="website"
              value={inputValues.website}
              setValue={setInputValues}
              noLabels={noLabels}
              margin={margin}
              small={small}
            />
          </div>
        )}

        {!quickContact && (
          <div className="uk-width-1-2@s">
            <InputField
              label="Phone number *"
              name="phone"
              value={inputValues.phone}
              setValue={setInputValues}
              noLabels={noLabels}
              margin={margin}
              small={small}
            />
          </div>
        )}

        {!quickContact && (
          <div className="uk-width-1-2@s">
            <InputField
              label="Website"
              name="website"
              value={inputValues.website}
              setValue={setInputValues}
              noLabels={noLabels}
              margin={margin}
              small={small}
            />
          </div>
        )}

        <div className="uk-width-1-1">
          <InputField
            label="Message *"
            name="message"
            value={inputValues.message}
            setValue={setInputValues}
            textArea
            noLabels={noLabels}
            margin={margin}
            small={small}
          />
        </div>

        <div className="uk-width-1-1 uk-text-center">
          <button
            type="submit"
            className={`uk-button ${blueButton ? "blue" : "purple"}`}
            value="Submit"
            name="submit"
          >
            {buttonLabel ? buttonLabel : "Submit"}
          </button>
        </div>
      </div>
    </form>
  )
}

const InputField = ({
  name,
  value,
  setValue,
  label,
  textArea = false,
  margin,
  small,
}) => {
  const onChange = (e) => {
    const value = e.target.value
    setValue((prev) => ({ ...prev, [name]: value }))
  }

  return textArea ? (
    <textarea
      placeholder={label}
      className={`uk-textarea custom-margin-${
        margin ? margin + "-" : ""
      }bottom ${!small && "uk-form-large"}`}
      cols="30"
      rows="6"
      required
      value={value}
      onChange={onChange}
    />
  ) : (
    <input
      type="text"
      className={`uk-input custom-margin-${margin ? margin + "-" : ""}bottom ${
        !small && "uk-form-large"
      }`}
      placeholder={label}
      required
      value={value}
      onChange={onChange}
    />
  )
}
Sign up to request clarification or add additional context in comments.

9 Comments

in this code for this part "setInputValues({})" how to set values? can you please explain?
api .contact(formData) .then((res) => { setMessage( quickContact ? "form_success_message_quick" : "form_success_message" ) // clear the input values here setInputValues({}) }) .catch((error) => { setMessage( quickContact ? "form_error_message_quick" : "form_error_message" ) })
This is a setter function returned from useState. If you're not familiar with it, check the documentation here. Instead of setting every property on the object, the code I provided simply resets it to an “empty” object which has the same effect, though you'll probably want to replace that with a static object with empty strings to avoid React complaining about converting from unmanaged to managed components.
But I get this error from this code. I have added it into your answer. Please check if you can.
@Perera Sorry about that—this is resulting from the SyntheticEvent being “recycled” by React by the time the callback runs. I've updated the onChange handler to address it.
|
0

Among the correct answer and especially the recommendations of @coreyward I want to add another approach that may help you or other users in the same trouble.

You can also use a useRef hook and ref, to your form tag and simply clear it with the native reset() function:

    export default ({
      noLabels = false,
      margin = "",
      small = false,
      blueButton = false,
      buttonLabel = null,
      quickContact = false,
      subject = "New message from website",
    }) => {
      const mailForm = useRef(null)
      //... more code
    }
  return (
    <form
      action="/send-mail.php"
      className="uk-form contact_form"
      method="post"
      onSubmit={handleSubmit}
      ref={mailForm}
    >
  )

Then, in your submit function you have exposed a mailForm.current as your form. You can simply:

const handleSubmit = (e) => {
    e.preventDefault()

    var formData = new FormData()
    Object.entries(inputValues).forEach(([key, value]) => {
      formData.set(key, value)
    })

    api
      .contact(formData)
      .then((res) => {
        setMessage(
          quickContact ? "form_success_message_quick" : "form_success_message"
        )

        // clear the input values here
        mailForm.curent.reset();
      })
      .catch((error) => {
        setMessage(
          quickContact ? "form_error_message_quick" : "form_error_message"
        )
      })
  }

3 Comments

Resetting the state of controlled components outside of the managed update flow would result in the new state being overridden on subsequent renders.
@Ferran Can we use rest() for controlled components. Sorry I'm not much familiar with react coding that is why asking..
@Perera of course you can, just need to take into account that if you have a state upon those fields it may cause a re-rendering issues

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.