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}}>