I am trying to use ChakraUI and React-Hook-Form to create my form. However, my errors are not working. I have tried not using chakra ui but still it does not work. Here is my code:
import React from 'react'
import { useForm } from "react-hook-form";
import "./App.css"
import { Input } from "#chakra-ui/react"
import { Text } from "#chakra-ui/react"
import {
Alert,
AlertIcon,
AlertTitle,
AlertDescription,
} from "#chakra-ui/react"
function App() {
const { register, handleSubmit, errors } = useForm();
const onSubmit = data => console.log(data);
return (
<div className="app-container">
<form onSubmit={handleSubmit(onSubmit)}>
<div className="header-container">
<Text fontSize="3xl" align="center" className="app-header">Finish the survey</Text>
</div>
<div className="email">
<Text fontSize="xl">Your Email</Text>
<Input name="email" placeholder="Your Email..." type="text" ref={register({ maxLength: { value: 23, message: "test" } })} />
{errors.email && (<span>{errors.email.message}</span>)}
</div>
</form>
</div>
)
}
export default App
Without knowing the version of the library you are using, I can't say for certain, but try changing
const { register, handleSubmit, errors } = useForm();
to
const { register, handleSubmit, formState: { errors } } = useForm();
I ran into the same problem when following their example off of the home page of the library's website and have since put in a PR.
Related
So I have been trying to make a form for adding a student in my website and everything is registering correctly except for my picture.
import { useEffect } from "react";
import { SubmitHandler, useForm } from "react-hook-form";
import FormInputField from "../../Components/FormInputField/FormInputField";
import { AddStudent } from "../../Types";
import { AddStudentFormFields } from "../../strings";
import style from "./AddStudentForm.module.css";
import { doc, getFirestore, setDoc } from "firebase/firestore";
const AddAStudent = () => {
const { register, handleSubmit, formState, reset } = useForm<AddStudent>();
const onsubmit: SubmitHandler<AddStudent> = (data) => {
console.log(data.newphotp.name);
return;
const db = getFirestore();
const colRef = doc(db, "Students", data.UniversityID);
setDoc(colRef, data);
};
useEffect(() => {
if (formState.isSubmitSuccessful) reset();
}, [formState, reset]);
return (
<div>
<form className={style.form} onSubmit={handleSubmit(onsubmit)}>
<div>
{AddStudentFormFields.map((item, index) => (
<FormInputField
key={index}
register={register}
name={item.field}
label={item.label}
/>
))}
<input type="file" {...register("newphotp")} />
</div>
<button className={style.button}>Add student </button>
<button type="reset" className={style.button}>
Reset form
</button>
</form>
</div>
);
};
export default AddAStudent;
I have tried to figure it out since an hour but it is not working sadly.
version of react-hook-form is 7.40.0
The input of type file return an array of type file so this :
console.log(data.newphotp[0].name)
worked fine.
I have a material ui design of a input type="file". How to validate the file and display the error message?
App.js
import React from "react";
import {useForm } from "react-hook-form";
import Button from "#mui/material/Button";
import { MuiFileInput } from "mui-file-input";
export default function App() {
const { register, handleSubmit, formState: { errors },} = useForm();
const [file, setFile] = React.useState(null);
const handleFile = (event) => {
setFile(event);
};
const onSubmit = (data) => {
alert(JSON.stringify(data.file?.name));
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<MuiFileInput sx={{ margin: 2 }}
{...register("uploadFile",
{required: "Please select an image."},
)}
onChange= {handleFile}
value={file}
label="Upload Image" placeholder='Select a file'
error={Boolean(errors.uploadFile)}
helperText={errors.uploadFile?.message}
/>
<Button type="submit" variant="contained" sx={{ margin: 2 }}>Submit</Button>
</form>
)
}
The error is displayed even after the file is selected
How to eliminate this error after file selection?
Remove Value props of input and just simply use MUI TextField and Style it
<TextField label="Upload Image" name="uploadImage" sx={{ margin: 2 }}
placeholder="Select a file"
onChange={handleFile} type="file"
{...register("uploadImage", {
required: "Please select a file",
})}
error={Boolean(errors.uploadImage)}
helperText={errors.uploadImage?.message}
/>
add reset where you included useForm and reset file field before selecting new file, this will reset error before selecting new file, and show error only if you did not select new file.
....
export default function App() {
const { register, handleSubmit, formState: { errors }, reset } = useForm();
....
const handleFile = (event) => {
reset({
'uploadFile': null
});
setFile(event);
};
this has a working example !
I'm new to React and still am trying to make sense of a few things. I'm using the react-form-dom library and after looking into the documentation I can't figure out what's going on with my project.
I have created a custom input component that takes in a few parameters. The problem is that when I try to log the value of the inputs I get undefined.
Input.jsx
import React, { useState } from 'react';
import './Input.scss';
export default function Input(props, {register, errors}) {
const [inputVal, setInputVal] = useState('');
const nameChange = (e) => {
setInputVal(e.target.value);
props.nameChange(e.target.value);
}
const legend = <span className='legend'>{props?.legend}</span>;
const showLength = <span className='legend'>{props.maxLength - inputVal.length}</span>;
return (
<div className="input-holder">
<input
ref={register}
type={props.type || 'text'}
id={props.id}
placeholder={props.placeholder}
value={inputVal}
onInput={nameChange}
maxLength={props.maxLength || ""}
/>
{ props.legend ? legend : null}
{ props.showLength && props.maxLength ? showLength : null }
</div>
)
}
Form.jsx
import React from 'react';
import { useForm } from "react-hook-form";
import Button from './Button';
import Input from './Input';
export default function UserForm(props) {
const { register, handleSubmit } = useForm();
function submitForm(data) {
console.log(data)
}
return (
<div className="user-form">
<form onSubmit={handleSubmit(submitForm)}>
<Input
placeholder="Name"
nameChange={(name) => props.userName(name)}
showLength="true"
maxLength="35"
legend="Remaining Char: "
id="name"
register={register}
/>
<Input
placeholder="E-mail"
type="email"
id="email"
register={register}
/>
<Button label="Buy" />
</form>
</div>
)
}
It seems that you are using react-hook-form
Checkout the example here
The onChange you are passing to the input tags are no longer needed with react-hook-form beacuse of register functionality of react-hook-form
also validations will be done react-hook-form
import React from 'react';
import { useForm } from "react-hook-form";
export default function UserForm(props) {
const { register, handleSubmit } = useForm();
const submitForm = (data) => {
console.log(data);
}
const onError = (err) => {
console.error(err);
}
return (
<div className="user-form">
<form onSubmit={handleSubmit(submitForm, onError)}>
<input
{...register("name", { //handles onChange, value, name, ref
maxLength: 35 // Your validations
})}
/>
<button>Buy</button>
</form>
</div>
)
}
Checkout docs for register
Form File Example
I'm on TS-React project, i got some inputs where scanning some barecode value. I'm using react-hook-form and the useForm Hook.
I got some little form (one input-text and one submit button) in a global form and i want to have an automation, when i press "Enter" on keyboard an action/event sends some fetch, or others.
With the and {handleSubmit} = useForm() , it work perfectly but, my input stay in focused and i need lost this focus...
So, how can i do this action ? i saw the blur() function but i didn't success to target my input from the handleSubmit function
import {Controller, useForm} from "react-hook-form"
const BasketContainer: FC = () => {
const { control, handleSubmit, setValue, watch, getValues, reset, formState: {errors}} = useForm<Basket>()
const handleScanIdSubmit = (data: any) => {
// Here my blur action
}
return (
<form onSubmit={handleSubmit(handleScanIdSubmit)}>
<Controller
render={({field: {ref, ...rest}}) => (
<InputText {...rest}
type={"text"}
label={"ID"}
errorMessage={errors.scanId.message}
/>)}
control={control}
name="scanId"
defaultValue={""}
rules={{required: "Field required"}}
/>
<Button type="submit"
/>
</form>
In advance, thanks for helps contributions :)
You can do it in a traditional way by calling blur() on an active element.
const handleScanIdSubmit = (data: any) => {
document.activeElement.blur();
}
Or you can create a reference with useRef;
import {Controller, useForm, useRef} from "react-hook-form"
const BasketContainer: FC = () => {
const controlReference = useRef(null);
const { control, handleSubmit, setValue, watch, getValues, reset, formState: {errors}} = useForm<Basket>();
const handleScanIdSubmit = (data: any) => {
controlReference.current.blur();
}
return (
<form onSubmit={handleSubmit(handleScanIdSubmit)}>
<Controller
render={({field: {ref, ...rest}}) => (
<InputText {...rest}
type={"text"}
label={"ID"}
ref={controlReference}
errorMessage={errors.scanId.message}
/>)}
control={control}
name="scanId"
defaultValue={""}
rules={{required: "Field required"}}
/>
<Button type="submit"/>
</form>
);
}
[update]
with typescript
import {useRef} from 'react';
function App() {
const controlReference = useRef(null);
const handleSubmit = async (e:React.ChangeEvent<any>) => {
e.preventDefault()
//with typescript
if (document.activeElement instanceof HTMLElement) {
document.activeElement.blur();
}
// controlReference.current.blur();
}
return (
<div className="App">
<label><textarea name="reply" ></textarea></label>
<div>
<button ref={controlReference} onClick={handleSubmit}>Submit</button>
</div>
</div>
);
}
export default App;
I am trying to do some mutations using graphql and react.js but I got a problem. Indeed I got the following message :
ESLint: React Hook "useMutation" is called in function "onSubmit" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter.(react-hooks/rules-of-hooks)
But I need to do the mutation when I click to validate the form and for that I need the function "onSUbmit"
Here is my code :
import React from "react";
import { Modal, Button } from "react-bootstrap";
import {useForm} from "react-hook-form";
import {gql, useMutation, useQuery} from '#apollo/client';
import {BrowserRouter, Link, Redirect} from "react-router-dom";
const Register = (props) => {
const { register, handleSubmit, errors } = useForm();
const onSubmit = data => {
let username = data.Username;
const GET_ACTIVITY = gql`
mutation Register($username: String!){
register(username: $username){
username
}
}
`
const [addchannel, { datas} ] = useMutation(GET_ACTIVITY);
}
console.log(props);
return (
<Modal show={props.show} onHide={props.onClose} centered>
<div className="login-form">
<h3 className="h3 mb-3 font-weight-normal" style={{textAlign: "center"}}> Register</h3>
<form className="form-signin" onSubmit={handleSubmit(onSubmit)} >
<div className="form-group">
<input
type="text"
id="inputUsername"
className="form-control"
placeholder="Username"
required=""
autoFocus=""
name="Username"
ref={register({ required: true})}
/>
<button className="btn btn-outline-success btn-block" type="submit" >
<i className="fas fa-sign-in-alt" /> Register
</button>
<hr />
</div>
</form>
</div>
</Modal>
);
}
export default Register;
Could you help me please ?
Thank you very much !
This line const [addchannel, { datas} ] = useMutation(GET_ACTIVITY); doesn't actually call the mutation. It just gives you the means to do it. You then have to call addChannel elsewhere in your code. That's why the call to useMutation has to be outside the onSubmit function. In your onSubmit function, you then call addChannel(). The component will then rerender and you can use datas.
EDIT : It seems to me that you though you could pass the username variable directly to the template literal. YOU WILL NEVER HAVE TO DO THIS! And even so, you'll have to pass it like this :
gql`
mutation Register($username: String!){
register(username: ${$username}){
username
}
}
`
But again, you should never have to build dynamic queries like this.
You have to call your mutation like so :
addChannel({ // this is the function returned by useMutation
variables: {
username // that's where you pass username !
}
})
So, there's no need to have GET_ACTIVITY inside your function, let alone the call to useMutation.
Don’t call Hooks inside loops, conditions, or nested functions.
you can try this.
const Register = (props) => {
const { register, handleSubmit, errors } = useForm();
const [addChannel, { datas} ] = useMutation(GET_ACTIVITY);
const GET_ACTIVITY= gql`
mutation Register($username: String!){
register(username: $username){
username
}
}
`
const onSubmit = data => {
addChannel({ variables: { username: data.Username } });;
}
...