Unform
Usage with TypeScript
Usage with TypeScript
Unform exposes all type definitions from within its packages, so it's unnecessary
to install @types
dependencies.
Form with TypeScript
When creating a form component using Unform and TypeScript, there are two main points to remember:
- The
onSubmit
function can be typed usingSubmitHandler<FormData>
whereFormData
is the format of data inputted by the user; - If you're using
useRef
to access form reference, remember to addFormHandles
as a type parameter to it;
1import React, { useRef } from 'react'2import { SubmitHandler, FormHandles } from '@unform/core'3import { Form } from '@unform/web'4import Input from './components/Input'56interface FormData {7 name: string8 email: string9}1011export default function MyForm() {12 const formRef = useRef<FormHandles>(null)1314 const handleSubmit: SubmitHandler<FormData> = data => {15 console.log(formRef)16 }1718 return (19 <Form ref={formRef} onSubmit={handleSubmit}>20 <Input name="name" />21 <Input name="email" />22 </Form>23 )24}
Simple input (ReactJS)
When creating a simple HTML input or any other HTML element used for the input
source, remember always to extend the element props. On the web, you can still
use the JSX.IntrinsicElements['element']
to get the props adapted to JSX.
Also, on the web (ReactJS), reference the global element inside useRef
hook
and always set the default value to null
.
1import React, { useEffect, useRef } from 'react'2import { useField } from '@unform/core'34interface Props {5 name: string6 label?: string7}89type InputProps = JSX.IntrinsicElements['input'] & Props1011export default function Input({ name, label, ...rest }: InputProps) {12 const inputRef = useRef<HTMLInputElement>(null)1314 const { fieldName, defaultValue, registerField, error } = useField(name)1516 useEffect(() => {17 registerField({18 name: fieldName,19 ref: inputRef,20 getValue: ref => {21 return ref.current.value22 },23 setValue: (ref, value) => {24 ref.current.value = value25 },26 clearValue: ref => {27 ref.current.value = ''28 },29 })30 }, [fieldName, registerField])3132 return (33 <>34 {label && <label htmlFor={fieldName}>{label}</label>}3536 <input37 id={fieldName}38 ref={inputRef}39 defaultValue={defaultValue}40 {...rest}41 />4243 {error && <span>{error}</span>}44 </>45 )46}
Simple input (React Native)
Let's create an InputProps
interface for the component. Also, we will create
an InputReference
interface to use on the useRef hook.
We can also tell registerField
what kind of value this Entry will store.
1import React, { useRef, useEffect, useCallback } from 'react'2import { TextInput, TextInputProps, Text } from 'react-native'3import { useField } from '@unform/core'45interface InputProps extends TextInputProps {6 name: string7 label: string8}910interface InputReference extends TextInput {11 value: string12}1314export default function Input({15 name,16 label,17 onChangeText,18 ...rest19}: InputProps) {20 const inputRef = useRef<InputReference>(null)2122 const { fieldName, registerField, defaultValue = '', error } = useField(name)2324 useEffect(() => {25 if (inputRef.current) inputRef.current.value = defaultValue26 }, [defaultValue])2728 useEffect(() => {29 registerField<string>({30 name: fieldName,31 ref: inputRef.current,32 getValue() {33 if (inputRef.current) return inputRef.current.value3435 return ''36 },37 setValue(ref, value) {38 if (inputRef.current) {39 inputRef.current.setNativeProps({ text: value })40 inputRef.current.value = value41 }42 },43 clearValue() {44 if (inputRef.current) {45 inputRef.current.setNativeProps({ text: '' })46 inputRef.current.value = ''47 }48 },49 })50 }, [fieldName, registerField])5152 const handleChangeText = useCallback(53 (value: string) => {54 if (inputRef.current) inputRef.current.value = value5556 if (onChangeText) onChangeText(value)57 },58 [onChangeText]59 )6061 return (62 <>63 {label && <Text>{label}</Text>}6465 <TextInput66 ref={inputRef}67 onChangeText={handleChangeText}68 defaultValue={defaultValue}69 {...rest}70 />71 </>72 )73}