Input Array
Form validation for password Matching to Show Error msg if paassword and confirm password not matched
const inputs =[
{
id:1,
name:"username",
type:"text",
placeholder:"username",
errorMsg:"username should be 3-16 characters and shouldn't include special character",
label:"Username",
pattern:`^[A-Za-z0-9]{3,16}$`,
required:true
},
{
id:2,
name:"email",
type:"email",
placeholder:"email",
errorMsg:"provide an valid email address",
label:"Email",
required:true
},
{
id:3,
name:"firstname",
type:"text",
placeholder:"first name",
errorMsg:"",
label:"Firstname"
},
{
id:4,
name:"lastname",
type:"text",
placeholder:"last name",
errorMsg:"",
label:"Lastname"
},
{
id:5,
name:"password",
type:"passwod",
placeholder:"password",
errorMsg:"password should be 8-20 characters and must contain 1 number 1 special character and upper case letter",
label:"Password",
pattern:`^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!##$%^&*])[a-zA-Z0-9!##$%^&*].{8,20}$`,
required:true
},
{
id:6,
name:"confirmPassword",
type:"passwod",
placeholder:"confirm password",
errorMsg:"password does not matched",
label:"Confirm password",
// pattern:values.password,
required:true
}
]
export default inputs
form component
import React, {useState } from 'react'
import FormInput from '../../components/formInput/FormInput'
import './form.css'
import inputs from '../../components/formInput/input'
const Form = () => {
const [values,setValues]=useState({
username:"",
email:"",
firstname:"",
lastname:"",
password:"",
confirmPassword:"",
});
const handleChange=(e)=>{
setValues({...values,[e.target.name]:e.target.value})
}
console.log(values)
return (
<div className='container'>
<form className='form'>
<h1>Register Form</h1>
{inputs.map(input=>(<FormInput key={input.id} {...input} value={values[input.name]} onChange={handleChange} />))}
<button>Register</button>
</form>
</div>
)
}
export default Form
Input Component
import React from 'react'
import './formInput.css'
const FormInput = (props) => {
const {label,errorMsg,onChange,id,...inputprops} = props;
return (
<div className='formInput'>
<label>{label}:</label>
<input {...inputprops} onChange={onChange} />
<span>{errorMsg}</span>
</div>
)
}
export default FormInput
Here in Input Array I want to match password with Confirm Password but those are in state
How to Access them into Array input for Validation, The password has to Access in the input Array for matching as value pair for Pattern for id: 6
You can make validation on each character input. for eg. somethink like that:
const Form = () => {
const [values,setValues]=useState({
username:"",
email:"",
firstname:"",
lastname:"",
password:"",
confirmPassword:"",
});
const validatePasswordRepeat = e => {
return e.target.value === values.passowrd
}
const validate = (e) => {
if(e.name === "confirmPassword")
return validatePasswordRepeat(e);
return true;
}
const handleChange = (e) => {
if(!validate(e));
return; // or show validation message, set error etc
setValues({...values,[e.target.name]:e.target.value})
}
return (
<div className='container'>
<form className='form'>
<h1>Register Form</h1>
{inputs.map(input=>(<FormInput key={input.id} {...input} value={values[input.name]} onChange={handleChange} />))}
<button>Register</button>
</form>
</div>
)
or when user will try send the form. (better option)
const Form = () => {
const [values,setValues]=useState({
username:"",
email:"",
firstname:"",
lastname:"",
password:"",
confirmPassword:"",
});
const handleChange=(e)=>{
setValues({...values,[e.target.name]:e.target.value})
}
const validate = e => {
//make validation on form state in e (event)
}
const handleSubmit = useCallback((e) => {
if(!validate(e))
//show errores
// handle form send
}, [])
return (
<div className='container'>
<form className='form' onSubmint={handleSubmit}>
<h1>Register Form</h1>
{inputs.map(input=>(<FormInput key={input.id} {...input} value={values[input.name]} onChange={handleChange} />))}
<button>Register</button>
</form>
</div>
)
}
export default Form
Related
help please I want to add value to state without overwriting. Currently, when adding a value, the array is overwritten. I want to use useState and I want to use the value from the form.
import {useState} from 'react';
const initialState = {
people: [
{email: 'Jan'},
{email: 'Izabela'},
{email: 'Michael'}
] }
const StateModification = () => {
const [names,setNames] = useState(initialState)
const handleSubmit = (e) => {
e.preventDefault();
}
const handleChange2 = (e) => {
setNames({
...names,
people: [{[e.target.name]: e.target.value}]
})
}
return (
<div>
<form onSubmit={handleSubmit}>
<label>E-mail</label>
<input
id='email'
type='text'
name='email'
value={names.email}
onChange={handleChange2}
/>
<button type='submit'>Add</button>
</form>
</div>`enter code here`
) }
export default StateModification;
I think you need to add an email in your data and after click on add button that email will store in people variable with your previous data so i have update your code and it should work for you.
import {useState} from 'react';
const initialState = {
people: [
{email: 'Jan'},
{email: 'Izabela'},
{email: 'Michael'}
] }
const StateModification = () => {
const [names,setNames] = useState(initialState)
const [email,setEmail] = useState("")
const handleSubmit = (e) => {
e.preventDefault();
setNames({
people: [...names.people, { email }]
})
}
const handleChange2 = (e) => {
e.preventDefault();
setEmail(e.target.value)
}
return (
<div>
<form onSubmit={handleSubmit}>
<label>E-mail</label>
<input
id='email'
type='text'
name='email'
value={email}
onChange={handleChange2}
/>
<button type='submit'>Add</button>
</form>
</div>
) }
export default StateModification;
here's my form
const AddSection = () => {
const { register, handleSubmit } = useForm();
const onSubmit = formData => {}
return <form onSubmit={() => { handleSubmit(onSubmit) }}>
<select {...register("id", { required: true })}>
{
options.map(o => (
<option key={`o-${o.id}`} value={o.id}>{m.name}</option>
))
}
</select>
</form>
}
In onSubmit I'm trying to get select value and text
I tried the following. but that's not perfect as for me + it doesn't work properly in all the cases.
const AddSection = () => {
const { register, handleSubmit, setValue } = useForm();
register("text")
...
return <form onSubmit={() => { handleSubmit(onSubmit) }}>
<select
{...register("id", { required: true })}
onChange={event => setValue("text", event.target[event.target.selectedIndex].text)}
>
...
</select>
</form>
}
Does anyone know the right way to do that ?
This works, it doesn't use the useForm hook but every time a new option is selected, it saves the value and text in the "user" state which is an object with the keys: value and text. Then console.log()s on submit.
import { useState } from "react";
const AddSection = () => {
const [user, setUser] = useState({});
let options = [
{ id: 1, name: "John Doe" },
{ id: 2, name: "Bob Builder" },
];
const handleSubmit = (e) => {
e.preventDefault();
console.log(user);
};
return (
<form onSubmit={handleSubmit}>
<select
required
onChange={(e) => {
setUser({
value: e.target.value,
text: e.target.options[e.target.selectedIndex].text,
});
}}
>
{options.map((o) => (
<option key={`o-${o.id}`} value={o.id}>
{o.name}
</option>
))}
</select>
<input type="submit" value="Submit" />
</form>
);
};
export default AddSection;
You did it the right way. Maybe
inside the onchange function, you can call another function onOptionSelect. The issue will probably be in passing values from the select component. So console it here and debug.
You can use react form Controller as below.
<Controller
control={control}
name="bank"
rules={{
required: 'Bank is required',
}}
render={({ onChange, name, value }) => (
<select
{...register("id", { required: true })}
onChange={(val: any) => {
onChange(val);
onOptionSelect(val);
}}
>
)}
/>
const onOptionSelect = (opt: any) => {
console.log(opt);
setValue('userId', opt._id);
setValue('username', opt.name);
};
You can also do it using a new useState variable as mentioned in #Benjamin Bialy's answer.
Refer https://react-hook-form.com/api/usecontroller/controller/
import React, { useEffect } from "react";
import ReactDOM from "react-dom";
import { useForm } from "react-hook-form";
import Multiselect from "./Multiselect.js";
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const App = () => {
const { handleSubmit, setValue, control, watch, reset } = useForm({
mode: "onBlur",
reValidateMode: "onChange",
shouldUnregister: true,
defaultValues: {
disciplines: []
}
});
useEffect(() => {
(async () => {
await sleep(50);
setValue("disciplines", ["bbb", "ccc"], { shouldValidate: true });
reset({ disciplines: ["bbb", "ccc"] });
})();
}, []);
const values = watch();
return (
<form onSubmit={handleSubmit(console.log)}>
<Multiselect
name={"disciplines"}
label={"Disciplines"}
control={control}
values={["aaa", "bbb", "ccc"]}
/>
<button>submit</button>
<pre>{JSON.stringify(values, null, 4)}</pre>
</form>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
You can get select value by:-
const AddSection = () => {
const { register, handleSubmit } = useForm();
const onSubmit = formData => {alert(JSON.stringify(formData.id));}
return <form onSubmit={() => { handleSubmit(onSubmit) }}>
<select {...register("id", { required: true })}>
{
options.map(o => (
<option key={`o-${o.id}`} value={o.id}>{o.name}</option>
))
}
</select>
</form>
}
After getting value if you can you can loop through options array to get the text also.
I did both mode the creation and edit in one form but the problem when I try to edit an element I get the right id value but couldn't retrieve the attributes values.
import { yupResolver } from "#hookform/resolvers/yup";
import { useState, useEffect } from "react";
import { useForm, SubmitHandler } from "react-hook-form";
import { useParams, useHistory, Link } from "react-router-dom";
import * as yup from "yup";
import {
getChoice,
postChoice,
updateChoice,
} from "../../../../api/remote.api";
import { CustomInput } from "../../../../components/lib";
import { Choice } from "../../../../models";
type Inputs = {
displayMessage: string;
value: string;
};
const schema = yup.object().shape({
displayMessage: yup.string().min(5, "Au minimum 5 chars").required(),
value: yup.string().min(5, "Au minimum 8 chars").required(),
});
const NewChoice = () => {
const { id } = useParams<{ id?: string }>();
const isAddMode = !id;
let history = useHistory();
const [submitting, setSubmitting] = useState<boolean>(false);
const [error, setError] = useState<string>();
const {
register,
handleSubmit,
setValue,
formState: { errors },
} = useForm<Inputs>({ resolver: yupResolver(schema) });
const onSubmit: SubmitHandler<Inputs> = (data: Inputs) => {
setSubmitting(true);
const choice = new Choice({
displayMessage: data.displayMessage,
value: data.value,
id: Number(id) ? Number(id) : -1,
});
submitForm(choice, id)
.then((chc) => {
setSubmitting(false);
history.goBack();
})
.catch((e) => {
const { message } = e.response.data;
if (message) {
setError(message);
}
setSubmitting(false);
});
};
const submitForm = (choice: Choice, id?: string) => {
return id ? updateChoice(Number(id!), choice) : postChoice(choice);
};
useEffect(() => {
if (!isAddMode) {
// get set form fields
getChoice(Number(id))
.then(
(choice: Choice) => {
setValue("displayMessage", choice.displayMessage);
setValue("value", choice.value);
},
(error) => {
history.push("/choices");
}
)
.catch((e) => {
console.log("error catch");
console.log(e);
});
}
}, [id, isAddMode, setValue, history]);
return (
<div className="container m-1">
<form
className={`flex-column justify-content-center`}
onSubmit={handleSubmit(onSubmit)}
>
<h1 className="h3 mb-3 fw-normal">Création d'un choix</h1>
<CustomInput
register={register}
label="Message affiché"
type="text"
id="displayMessage"
error={errors.displayMessage?.message}
placeholder="Display Message"
/>
<CustomInput
register={register}
label="Valeur du choix"
type="text"
id="value"
error={errors.value?.message}
placeholder="Choice Value"
/>
{error && <div className="invalid-feedback d-block">{error}</div>}
<Link to={"."} className="btn btn-small btn-warning mt-3 mr-2">
Cancel
</Link>
<button
className="btn btn-small btn-primary mt-3"
type="submit"
disabled={submitting}
>
{isAddMode ? "Création" : "Mise à jour"}
</button>
</form>
</div>
);
};
export default NewChoice;
and i tried to look a little bit on stack and other websites but couldn't solve this 5 days bug , in a result i just get a blank page with the appropriate id
and the element should be in this file .
export const CustomInput = ({
register,
label,
type,
id,
error,
placeholder,
}: {
register: any;
label: string;
placeholder: string;
type: string;
id: string;
error?: string;
}) => {
return (
<>
<label htmlFor={id}>{label}</label>
<div className="form-floating">
<input
type={type}
className="form-control"
id={id}
placeholder={placeholder}
{...register(id)}
/>
{error && <p className="invalid-feedback d-block">{error}</p>}
</div>
</>
);
};
Try a new state:
const [isToUpdate, setUpdate] = useState<boolean>(false);
Add it to useEffect array:
[id,isToUpdate ....]
Add setUpdate to where you are setting values after setValue("value",choice.value);
setUpdate(true);
After the login click i am not able to render the data that i got from Login form into the HomePage as i want to see the username and password into the HomePage after i entered the username and password that has already been in my local storage(at present this is not done as i am just checking the login with the dummy data).
App Component:
import LoginForm from "./Component/LoginForm/LoginForm";
import HomePage from "./Component/HomePage/HomePage";
import { useState, useEffect } from "react";
function App() {
const user = [{ username: "admin" }, { password: "admin" }];
const [isLoggedIn, setIsLoggedIn] = useState(false);
useEffect(() => {
const isUserLoggedIn = localStorage.getItem("isLoggedInn");
if (isUserLoggedIn === "1") {
setIsLoggedIn(true);
}
}, []);
const loginHandler = () => {
localStorage.setItem("isLoggedInn", "1");
setIsLoggedIn(true);
// return [username,password];
};
const logoutHandler = () => {
localStorage.removeItem("isLoggedInn");
setIsLoggedIn(false);
};
const onSaveDataHandler = (newData) =>{
console.log(newData);
console.log('inside app');
}
const dataFormHandler = (username,password) => {
return username;
}
return (
<div>
{!isLoggedIn && <LoginForm adminUser={user} onLogin={loginHandler} onSaveData={onSaveDataHandler} dataForm={dataFormHandler}/>}
{isLoggedIn && <HomePage onLogout={logoutHandler} user={dataFormHandler[0]}/>}
</div>
);
}
export default App;
LoginForm Component:
import styles from "./LoginForm.module.css";
import { useState } from "react";
import SignUp from "../SignUp/SignUp";
const LoginForm = (props) => {
const [enteredUsername, setEnteredUsername] = useState("");
const [enteredPassword, setEnteredPassword] = useState("");
const [isTrue, setTrue] = useState(true);
const [isClicked, setIsClicked] = useState(false);
const onChangeHandlerUsername = (event) => {
setEnteredUsername(event.target.value);
if (event.target.value === enteredUsername) {
setTrue(true);
}
};
const onChangeHandlerPassword = (event) => {
setEnteredPassword(event.target.value);
if (event.target.value === enteredPassword) {
setTrue(true);
}
};
const onSubmitHandler = (event) => {
event.preventDefault();
if (
enteredUsername === props.adminUser[0].username &&
enteredPassword === props.adminUser[1].password
) {
props.onLogin();
props.dataForm(enteredUsername,enteredPassword);
} else {
setTrue(false);
}
};
const onClickHandler = () => {
setIsClicked(true);
};
const sendDataToChild = (entereduserData) =>{
const userData = {
...entereduserData,
id: Math.random().toString()
};
props.onSaveData(userData);
}
return (
<>
{isClicked &&
enteredUsername !== props.adminUser[0].username &&
enteredPassword !== props.adminUser[1].password ? (
<SignUp name={enteredUsername} dataTransfer={sendDataToChild}/>
) : (
<form onSubmit={onSubmitHandler}>
<h1 className={styles.blink_me}>W E L C O M E</h1>
<div className={`${styles.box} ${!isTrue && styles.wrong}`}>
<h1>Login</h1>
<input
type="text"
value={enteredUsername}
placeholder="Enter Username"
className={styles.email}
onChange={onChangeHandlerUsername}
></input>
<input
type="password"
value={enteredPassword}
placeholder="Enter Password"
className={styles.email}
onChange={onChangeHandlerPassword}
></input>
<div>
<button className={styles.btn}>Sign In</button>
</div>
<div>
<button
onClick={onClickHandler}
type="button"
className={styles.btn2}
>
Sign Up
</button>
</div>
<div>
Forget Password
</div>
</div>
</form>
)}
</>
);
};
export default LoginForm;
HomePage Component:
import styler from './HomePage.module.css';
const HomePage = (props) =>{
return(
<div className={styler.body}>
<h2>Login Successfull !</h2>
<p>Name: {props.user}</p>
<p>Password: {props.pass}</p>
<button type='submit' onClick={props.onLogout} className={styler.button}>Logout</button>
</div>
);
}
export default HomePage;
I found some points which I would like to highlight in the code.
dataFormHandler function: when this function is getting called from the LoginForm component, the output is not getting stored anywhere. See the below code snippet from the LoginForm component.
props.dataForm(enteredUsername,enteredPassword)
You need to store the username and password somewhere. For this you can directly utilize the onLogin() method of the LoginForm component and pass in the enteredUsername and enteredPassword as the arguments like below:
props.onLogin(enteredUsername, enteredPassword);
and then store them somewhere from the App component.
const loginHandler = (username, password) => {
localStorage.setItem("isLoggedInn", "1");
setIsLoggedIn(true);
localStorage.setItem("currentUsername", username);
localStorage.setItem("currentPassword", password);
// return [username,password];
};
Your dataFormHandler function returns just the username. That doesn't make sense to me. You can instead return an array of 2 elements, username and the password.
const dataFormHandler = () => {
return [
localStorage.getItem("currentUsername"),
localStorage.getItem("currentPassword")
];
};
Now to access these values in the HomePage component, you just need to access them as props.user[0] and props.user[1]
The code for all the three components can be found below: (ps- I have changed some file paths and removed the classNames and styles just to make it work on my machine)
App Component:
import LoginForm from "./components/LoginForm";
import HomePage from "./components/HomePage";
import { useState, useEffect } from "react";
function App() {
const user = [{ username: "admin" }, { password: "admin" }];
const [isLoggedIn, setIsLoggedIn] = useState(false);
useEffect(() => {
const isUserLoggedIn = localStorage.getItem("isLoggedInn");
if (isUserLoggedIn === "1") {
setIsLoggedIn(true);
}
}, []);
const loginHandler = (username, password) => {
localStorage.setItem("isLoggedInn", "1");
setIsLoggedIn(true);
localStorage.setItem("currentUsername", username);
localStorage.setItem("currentPassword", password);
// return [username,password];
};
const logoutHandler = () => {
localStorage.removeItem("isLoggedInn");
setIsLoggedIn(false);
};
const onSaveDataHandler = (newData) => {
console.log(newData);
console.log("inside app");
};
const dataFormHandler = () => {
return [
localStorage.getItem("currentUsername"),
localStorage.getItem("currentPassword")
];
};
return (
<div>
{!isLoggedIn && (
<LoginForm
adminUser={user}
onLogin={loginHandler}
onSaveData={onSaveDataHandler}
dataForm={dataFormHandler}
/>
)}
{isLoggedIn && (
<HomePage onLogout={logoutHandler} user={dataFormHandler()} />
)}
</div>
);
}
export default App;
LoginForm Component:
import { useState } from "react";
const LoginForm = (props) => {
const [enteredUsername, setEnteredUsername] = useState("");
const [enteredPassword, setEnteredPassword] = useState("");
const [isTrue, setTrue] = useState(true);
const [isClicked, setIsClicked] = useState(false);
const onChangeHandlerUsername = (event) => {
setEnteredUsername(event.target.value);
if (event.target.value === enteredUsername) {
setTrue(true);
}
console.log(enteredUsername);
};
const onChangeHandlerPassword = (event) => {
setEnteredPassword(event.target.value);
if (event.target.value === enteredPassword) {
setTrue(true);
}
console.log(enteredPassword);
};
const onSubmitHandler = (event) => {
event.preventDefault();
if (
enteredUsername === props.adminUser[0].username &&
enteredPassword === props.adminUser[1].password
) {
props.onLogin(enteredUsername, enteredPassword);
// props.dataForm(enteredUsername, enteredPassword);
} else {
setTrue(false);
}
};
const onClickHandler = () => {
setIsClicked(true);
};
const sendDataToChild = (entereduserData) => {
const userData = {
...entereduserData,
id: Math.random().toString()
};
props.onSaveData(userData);
};
return (
<>
{isClicked &&
enteredUsername !== props.adminUser[0].username &&
enteredPassword !== props.adminUser[1].password ? (
<SignUp name={enteredUsername} dataTransfer={sendDataToChild} />
) : (
<form onSubmit={onSubmitHandler}>
<h1>W E L C O M E</h1>
<div>
<h1>Login</h1>
<input
type="text"
value={enteredUsername}
placeholder="Enter Username"
onChange={onChangeHandlerUsername}
></input>
<input
type="password"
value={enteredPassword}
placeholder="Enter Password"
onChange={onChangeHandlerPassword}
></input>
<div>
<button>Sign In</button>
</div>
<div>
<button onClick={onClickHandler} type="button">
Sign Up
</button>
</div>
<div>
Forget Password
</div>
</div>
</form>
)}
</>
);
};
export default LoginForm;
HomePage Component:
const HomePage = (props) => {
const name = props.user[0];
const pass = props.user[1];
return (
<div>
<h2>Login Successfull !</h2>
<p>Name: {name}</p>
<p>Password: {pass}</p>
<button type="submit" onClick={props.onLogout}>
Logout
</button>
</div>
);
};
export default HomePage;
Your HomePage user prop is invalid, as you pass a function there (and what's more wrong, you try to get this function's 0th element, as it were an array).
What you should do instead is store the username somewhere (accessible from within your App component), and pass it directly as the HomePage prop.
To give you an idea, your dataFormHandler only returns the first of its two arguments, so in my opinion it's pointless. Your scenario'd work under such conditions:
const myusername = 'mock username';
const mypassword = 'mock password';
return <HomePage onLogout={logoutHandler} user={dataFormHandler(myusername, mypassword)}/>
edit
You jave to modify your loginHandler(username, password), inside it: set the values as state, then do what I wrote earlier.
I have a React component that looks like this. It's a simple form with an input element of type email. As usual, when the user types some text, I fire a callback for the onChange event. This is what the code looks like.
import React, { PureComponent, Fragment } from "react";
import CheckCircleOutline from "mdi-react/CheckCircleOutlineIcon";
import AccountOutlineIcon from "mdi-react/AccountOutlineIcon";
import styles from "./ForgotPassword.module.scss";
class ForgotPasswordFrom extends PureComponent {
constructor() {
super();
this.state = {
email: ""
};
}
updateEmailField = e => {
this.setState({ email: e.target.value });
};
resetPassword = async e => {
e.preventDefault();
const { email } = this.state;
this.props.onSubmit(email);
};
render() {
const { showResetMessage, email } = this.props;
return (
<Fragment>
<form className="form aim-form">
{!showResetMessage ? (
<Fragment>
<div className="form__form-group">
<div className="form__form-group-field">
<div className="form__form-group-icon">
<AccountOutlineIcon />
</div>
<input
name="email"
type="email"
onChange={this.updateEmailField}
placeholder="Enter Registered Email Address"
className="email-input"
data-testid="forgot_password_input"
/>
</div>
</div>
<button
type="button"
className="btn btn-primary account__btn account__btn--small login-btn"
onClick={this.resetPassword}
data-testid="forgot_password"
>
Submit
</button>
</Fragment>
) : (
<div className={styles.messageContainer}>
<CheckCircleOutline size={50} />
<div className={styles.emailMessage}>
<div>We have sent an email to {email}.</div>
<div>Click the link in the email to reset your password</div>
</div>
</div>
)}
</form>
</Fragment>
);
}
}
export default ForgotPasswordFrom;
I am trying to write a test for when the input field's change event is simulated. This test should basically ensure that the updateEmailField function is triggered. However, no matter what I try, I cannot get the test to pass. The error I get is that the mock function is not called. Any idea what I'm doing wrong?
it("should have called the function", () => {
const wrapper = mount(<ForgotPasswordForm />);
const instance = wrapper.instance();
instance.updateEmailField = jest.fn()
const input = wrapper.find(`[data-testid='forgot_password_input']`);
input.simulate('change', { target: { value: 'test ' } });
expect(instance.updateEmailField).toHaveBeenCalled();
})
Try this code.
it("should have called the function", () => {
jest.spyOn(ForgotPasswordForm.prototype, 'updateEmailField');
const wrapper = mount(<ForgotPasswordForm />);
afterAll(() => {
ForgotPasswordForm.prototype.updateEmailField.mockRestore();
});
const input = wrapper.find(`[data-testid='forgot_password_input']`);
input.simulate('change', { target: { value: 'test ' } });
expect(wrapper.instance().updateEmailField).toHaveBeenCalled();
})