Home > Blockchain >  How to turn a handleSubmit form function into a reusable one
How to turn a handleSubmit form function into a reusable one

Time:07-06

I a using the React-Bootstrap handleSubmit function to validate a form , submit it , and at the same time call sign() to register my user. Since I will be using a similar form to login the user (just changing the function that gets called inside), and probably in more views, I would like to "outsource" this function, turn it into a reusable one, put in a different file, and call it when needed, passing the arguments required , to make my code cleaner and less repetitive. But I am quite lost about where to start and how I should do it. Any help is much appreciated.

In my SignUp.jsx component :

import { useState, useContext } from "react";
import Form from "react-bootstrap/Form";
import Button from "react-bootstrap/Button";
import Col from "react-bootstrap/Col";
import Row from "react-bootstrap/Row";

function SignUp() {
  const [validated, setValidated] = useState(false);

  const handleSubmit = (e) => {
    const form = e.currentTarget;
    console.log(form);
    if (form.checkValidity() === false) {
      e.preventDefault();
      e.stopPropagation();
    }
    setValidated(true);
    if (form.checkValidity() === true) {
      e.preventDefault();
      sign();
    }
  };
const sign = () => {
    console.log("user signed up");
  }
  const handleChangeHandler = (e) => {
    setNewUser({ ...newUser, [e.target.name]: e.target.value });
  };


// I omitted many Form fields to reduce the code
  return (
    <div className="containerSignUp">
      <div className="innerContainerSignUp">
        <h1>Sign Up</h1>
        <Form noValidate validated={validated} onSubmit={handleSubmit}>
          <Row>
            <Col>
              <Form.Group className="mb-3" controlId="formBasicUserName">
                <Form.Label>Username</Form.Label>
                <Form.Control
                  required
                  name="userName"
                  value={newUser.userName ? newUser.userName : ""}
                  type="text"
                  onChange={handleChangeHandler}
                />
                <Form.Control.Feedback type="invalid">
                  Please pick a user name.
                </Form.Control.Feedback>
              </Form.Group>
            </Col>
          </Row>
          <Button type="submit" className="signButton">
            Signup
          </Button>
        </Form>
      </div>
    </div>
  );
}

export default SignUp;

My attempt : I created a file validateForm.js :

const handleSubmit = (event, func) => {
  // const [validated, setValidated] = useState(false); // I cannot use a state outside a react component.

  const form = e.currentTarget;
  console.log("form", form);

  if (form.checkValidity() === false) {
    e.preventDefault();
    e.stopPropagation();
  }
  setValidated(true);
  if (form.checkValidity() === true) {
    e.preventDefault();
    func();
  }
};

export { handleSubmit };

In signUp.jsx I import it, and call it :

import { handleSubmit } from "../utils/validateForm";

And call it when I submit the form :

<Form noValidate validated={validated}
      onSubmit={(e) => {
            handleSubmit(e, sign, setValidated(true));}}>

CodePudding user response:

You can achieve this using a custom hook:

useHandleSubmit.js

const useHandleSubmit() {
    const [validated, setValidated] = useState(false);

    const handleSubmit = (event, func) => {

      const form = event.currentTarget;
      console.log("form", form);

      if (form.checkValidity() === false) {
        event.preventDefault();
        event.stopPropagation();
      }
      // maybe you must move this inside the next `if`, otherwise move it to the end
      setValidated(true);
      if (form.checkValidity() === true) {
        event.preventDefault();
        func();
      }
    };

    return { handleSubmit, validated };

}

export default useHandleSubmit;

In signUp.jsx:

import useHandleSubmit from '../utils/useHandleSubmit';

...

const { handleSubmit, validated } = useHandleSubmit();

...

<Form noValidate validated={validated}
      onSubmit={(e) => {
            handleSubmit(e, sign}}>
  • Related