- You can use
useRef
to get the values of input field in the form
useRef
is a buit-in hook which you can use to reference any DOM element
- Common practice is to initialize to null
- Returns ref object
- Create ref object and assign to control
const nameRef = useRef(null);
<input ref={nameRef} />
console.log(nameRef.current.value)
current
prop returns referenced DOM element
if(nameRef.current.value !== null)
console.log(nameRef.current.value);
useRef<HTMLInputElement>();
current
current
property references DOM node. The initial value used to set current
property
- Initially
ref
has no access to DOM node. DOM gets created after react renders. The current
prop is set to DOM after component is rendered and set to null
when node is removed from screen
current
prop points to either DOM or null
- If no value is passed to
useRef
, the current prop will be undefined and willl cause issues
- Always initialize with null
Controlled Components
- In HTML, form elements such as
<input>
, <textarea>
, and <select>
typically maintain their own state and update it based on user input
- In React, mutable state is typically kept in the state property of components, and only updated with
setState()
.
- We can combine the two by making the React state be the
single source of truth
.
- Then the React component that renders a form also controls what happens in that form on subsequent user input.
- An input form element whose value is controlled by React in this way is called a
controlled component
.
const [person, setPerson] = useState({name: "",
age: ""})
<form>
<input onChange={(event) => setPerson({...person, name: event.target.value})} value={person.name} />
<input onChange={(event) => setPerson({...person, age: parseInt(event.target.value)})} value={person.age} />
</form>
npm i react-hook-form@7.43
import {useForm} from "react-hook-form";
const {register, handleSubmit} = useForm();
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("name")} />
</form>
onSubmit = (data:FieldValuess) => console.log(data);
Applying Validations
interface FormData {
name: string;
age: string;
}
const {register, handleSubmit, formState: {errors}} = useForm<FormData>();
<input {...register("name", {required: true, minLength: 3})} />
{errors.name?.type === "required" && <p>The name field is required</p> }
{errors.name?.type === "minLength" && <p>The name must be atleat 3 characters</p> }
Schema Based Validation
- Popular libraries
- Install zod
npm i zod@3.20.6
import {z} from "zod";
const schema = z.object({
name: z.string().min(3, {message: "Name must be at least 3 chars"}),
age: z.number({invalid_type_error: "Age is required"}).min(18, {message: "Age must be at least 18"})
})
type FormData = z.infer<typeof schema>;
npm i @hookform/resolvers@2.9.11
import {zodResolver} from "@hookform/resolvers/zod";
- Pass schema to react hook form using zod resolver
useForm<FormData>({resolver: zodResolver(schema)});
register("age", {valueAsNumber: true})
{errors.name && <p>{errors.name.message}</p> }
const {register, handleSubmit, formState: {errors, isValid}} = useForm();
- Add disblaed attribute based on isValid
<button disabled={!isValid}></button>