this is my first time using hooks I don't know How can I clear input fields after submit, form.reset() doesn't work
import { useForm } from "react-hook-form";
import....
export default function AddUser() {
const URL = "http://localhost:3000/AddUser";
const { register, handleSubmit, errors } = useForm();
const onSubmit = (data) => {
if (data) {
axios.post(URL, data);
}
form.reset()
};
here is the return part
return (
<form onSubmit={handleSubmit(onSubmit)} noValidate>
<div className="container">
<input type="text" name="name" placeholder="Name" ref={register({required: true})}/>
<input type="radio" name="gender" value="male" ref={register({ required: true })}/>:Male
<input type="radio" name="gender" value="female" ref={register({ required: true })}/:Female
<button type="submit" className="btn "> add</button>
</div>
</form>
);
}
thanks in advance
//////////
You need to import reset from useForm() hook to be able to use it outside of your tags.
so
const { register, handleSubmit, errors, reset } = useForm();
then on your submit function
const onSubmit = (data) => {
if (data) {
axios.post(URL, data);
}
reset({})
};
Something along those lines should work.
You need to set a default state to set when your click is handle, that way your component will reset on every submit. And yet, and if you wanna prevent default you must set event.preventDefault(); inside the onSubmit function
import { useForm, useState } from "react-hook-form";
import....
export default function AddUser() {
const [formState, setFormState] = useState({})
const URL = "http://localhost:3000/AddUser";
const { register, handleSubmit, errors } = useForm();
const onSubmit = (data) => {
if (data) {
setFormState(data)
axios.post(URL, formState);
}
form.reset()[![enter image description here][1]][1]
};
Related
I am using react, typescript, the react-hook-form library and 'yup' for form validation.
If the form is validated correctly using the react-hook-form library then I want an email to be sent using 'Email JS' library.
When the form is submitted, the handleSubmit function from react-hook-form library is called.
docs for handleSubmit
If there are no errors, then the sendEmail function should be called, and the email sent with Email JS.
I have put the code below, the important part is the form's 'onSubmit' property.
import React, { useRef, useState } from "react";
import { useForm } from "react-hook-form";
import { yupResolver } from "#hookform/resolvers/yup";
import { string, number, object, InferType } from "yup";
import { url } from "inspector";
import emailjs from "#emailjs/browser";
function onSubmit(values: Props) {}
type Props = InferType<typeof schema>;
const schema = object({
firstName: string().required("First name is required"),
lastName: string().required("Last name is required"),
});
function FormEmail() {
const form = useRef(null);
const [value, setValue] = useState<string | undefined>();
const {
register,
handleSubmit,
formState: { errors },
} = useForm<Props>({
resolver: yupResolver(schema),
});
const sendEmail = (e: { preventDefault: () => void }) => {
e.preventDefault();
emailjs
.sendForm(
'YOUR_SERVICE_ID', 'YOUR_TEMPLATE_ID', form.current!, 'YOUR_PUBLIC_KEY'
)
.then(
(result: { text: any }) => {
console.log(result.text);
},
(error: { text: any }) => {
console.log(error.text);
}
);
};
return (
<div>
<form onSubmit={handleSubmit(onSubmit)} ref={form}>
<h3>First Name</h3>
<input
id="firstName"
type="text"
{...register("firstName")}
/>
<span className="error">{errors?.firstName?.message}</span>
<h3>Last Name</h3>
<input
id="lastName"
type="text"
{...register("lastName")}
/>
<span className="error">{errors?.lastName?.message}</span>
<button type="submit">
Submit
</button>
</form>
</div>
);
}
export default FormEmail;
Any help on this would be appreciated!
I'm trying to validate a simple form with a single input just for practice. I also don't want the value that the user types in the input to disappear after page refresh, for that reason, I did a little bit of searching and found out about saving that data using localStorage. After trying to implement that for a while, I managed to do that, when I refresh the page, the value is still there. However, now, when I'm trying to validate the form using useForm from react-hook-form, It just doesn't work for some reason, when I try to use that same useForm logic with an input without using localStorage, It works just fine, but while trying to add localStorage functionality, then it doesn't. I hope I'm describing my problem at least okey, here's the code :
import React, {useEffect, useState } from "react";
import "./App.css"
import { useForm } from "react-hook-form";
const getForm = () => {
const storedValues = localStorage.getItem("form");
if(!storedValues) return {
name: "",
age: ""
}
return JSON.parse(storedValues);
}
function Home() {
const [values, setValues] = useState(getForm)
const {register, handleSubmit, watch} = useForm();
const handleChange = (e) => {
setValues((previousValues) => ({
...previousValues,
[e.target.name]: e.target.value,
}))
}
const onSubmit = async data => { console.log(data); };
useEffect(()=>{
localStorage.setItem("form", JSON.stringify(values))
}, [values])
return (
<div className="container">
<form onSubmit={handleSubmit(onSubmit)}>
<input value={values.name} onChange={handleChange} name="name" placeholder="name" />
<input value={values.age} onChange={handleChange} name="age" placeholder="age"/>
<button type="submit">Submit</button>
</form>
</div>
)
}
export default Home;
This code works fine since I'm not adding useForm register to the input, but if I do that, then It gets buggy, like this :
<input value={values.name} onChange={handleChange} name="name" placeholder="name" {...register("name")} />
The latest code only works If I remove the value atrribute from the input, but I can't do that, If I do, I can't use localStorage anymore.
Looking at the documentation, you had the syntax a little off with your register function. That function takes a second argument, which is an object of props, and that is where you want to define value, name and onChange.
Like this:
<input
placeholder="name"
{...register("name", {
onChange: handleChange,
name: "name",
value: values.name
})}
/>
Here is the full code I have working on a codesandbox. That's really all I changed, expect removing the watch import.
import React, { useEffect, useState } from "react";
import "./styles.css";
import { useForm } from "react-hook-form";
const getForm = () => {
const storedValues = localStorage.getItem("form");
if (!storedValues)
return {
name: "",
age: ""
};
return JSON.parse(storedValues);
};
function Home() {
const [values, setValues] = useState(getForm);
const { register, handleSubmit } = useForm();
const handleChange = (e) => {
setValues((previousValues) => ({
...previousValues,
[e.target.name]: e.target.value
}));
};
const onSubmit = async (data) => {
console.log(data);
};
useEffect(() => {
localStorage.setItem("form", JSON.stringify(values));
}, [values]);
return (
<div className="container">
<form onSubmit={handleSubmit(onSubmit)}>
<input
placeholder="name"
{...register("name", {
onChange: handleChange,
name: "name",
value: values.name
})}
/>
<input
value={values.age}
onChange={handleChange}
name="age"
placeholder="age"
/>
<button type="submit">Submit</button>
</form>
</div>
);
}
export default Home;
I have a form that have an onSubmit, in that callback I have a uploady.showFileUpload(), but the code after uploady.showFileUpload() is executed.
Now the question is how can I wait for uploady, and then execute the rest of the code?
const handleSubmit2 = useCallback((e)=> {
uploady.showFileUpload(); //(HERE SHOULD WAIT FOR IT TO FINISH FILE SELECT)
//OTHER CODE
});
This codesandbox should be helpful in the case of using Uploady with a form:
https://codesandbox.io/s/react-uploady-inside-form-ys1wx
The idea is that you show the file selection prompt separately from submitting the form:
import React, { useState, useCallback, useMemo, forwardRef } from "react";
import Uploady, {
useUploadyContext
} from "#rpldy/uploady";
import { asUploadButton } from "#rpldy/upload-button";
const MyUploadField = asUploadButton(
forwardRef(({ onChange, ...props }, ref) => {
return (
<div {...props} ref={ref} id="form-upload-button" title={text}>
Select file
</div>
);
})
);
const MyForm = () => {
const [fields, setFields] = useState({});
const [fileName, setFileName] = useState(null);
const uploadyContext = useUploadyContext();
const onSubmit = useCallback(() => {
uploadyContext.processPending({ params: fields });
}, [fields, uploadyContext]);
const onFieldChange = useCallback(
(e) => {
setFields({
...fields,
[e.currentTarget.id]: e.currentTarget.value
});
},
[fields, setFields]
);
return (
<form>
<MyUploadField autoUpload={false} />
<input
onChange={onFieldChange}
id="field-name"
type="text"
placeholder="your name"
/>
<SubmitButton
id="form-submit"
type="button"
onClick={onSubmit}
>
Submit Form
</SubmitButton>
</form>
);
};
<Uploady
clearPendingOnAdd
destination={{ url: "[upload-url]" }}
multiple={false}
>
<MyForm />
</Uploady>
Selection is achieved by using the asUploadButton HOC. You can of course do so yourself as you did with uploady.showFileUpload();.
Then, the submit button uses uploady's processPending method to start uploading.
I'm trying to make a little login screen with functional React. I have an input button that I want to click and have the login post happen. For the life of me, I can't get the handler to fire. loginPressed just won't get called. I'm sure it's something easy that I'm overlooking.
import * as React from 'react';
import axios from 'axios'
export default function Login() {
const [email, setEmail] = React.useState([]);
const [password, setPassword] = React.useState([]);
const loginPressed = () => {
var body = {
'email': email,
'password': password
}
axios.post('login', body)
.then(response => {
})
}
return (
<div>
<p>Username:</p>
<p><input type="text" name="email" onChange={(e) => {setEmail(e.target.value)}}/></p>
<p>Password:</p>
<p><input type="password" name="password" onChange={(e) => {setPassword(e.target.value)}}/></p>
<p>
<input type='button' value='Login' onClick={loginPressed}/>
</p>
</div>
);
}
You should use form with onSubmit={loginPressed}. Instead of input use button html element with type of submit.
I'm trying to implement a login function to my react app.
import React, { useState, useEffect } from 'react'
import { useQuery, useLazyQuery, useMutation } from "#apollo/client"
import { useForm } from "react-hook-form"
import { LOGIN } from '../queries/queries'
const Login = () => {
const [formValue, setFormValue] = useState({})
const { loading, error, data } = useQuery(LOGIN, {
variables: {
email: formValue.email,
password: formValue.password
}
})
const { register, handleSubmit } = useForm()
const onSubmit = (value) => {
setFormValue(value)
}
if (loading) return <p>loading</p>
return(
<>
<form onSubmit={handleSubmit(onSubmit)} >
<input
type="text"
name="email"
placeholder="E-mail"
ref={register}
/>
<input
type="password"
name="password"
placeholder="Password"
ref={register}
/>
<button type="submit">
Login
</button>
</form>
</>
)
}
When I code console.log(data.user) for example, error happens because user is not undefined.
I know I can get object from data if I code variables directly, but I want to get it after handleSubmit.
I think if I can make data object initially, error would not happen.
Then is there any way to do that?
try "data?.user" instead of "data.user" when referring to that object attribute
the question mark should disable the error if the object doesnt exist
update:
you can also try declaring data as an empty objec literal:
{ loading, error, data = {} }