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 using SubmitHandler<FormData> where FormData is the format of data inputted by the user;
  • If you're using useRef to access form reference, remember to add FormHandles 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'
5
6interface FormData {
7 name: string
8 email: string
9}
10
11export default function MyForm() {
12 const formRef = useRef<FormHandles>(null)
13
14 const handleSubmit: SubmitHandler<FormData> = data => {
15 console.log(formRef)
16 }
17
18 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'
3
4interface Props {
5 name: string
6 label?: string
7}
8
9type InputProps = JSX.IntrinsicElements['input'] & Props
10
11export default function Input({ name, label, ...rest }: InputProps) {
12 const inputRef = useRef<HTMLInputElement>(null)
13
14 const { fieldName, defaultValue, registerField, error } = useField(name)
15
16 useEffect(() => {
17 registerField({
18 name: fieldName,
19 ref: inputRef,
20 getValue: ref => {
21 return ref.current.value
22 },
23 setValue: (ref, value) => {
24 ref.current.value = value
25 },
26 clearValue: ref => {
27 ref.current.value = ''
28 },
29 })
30 }, [fieldName, registerField])
31
32 return (
33 <>
34 {label && <label htmlFor={fieldName}>{label}</label>}
35
36 <input
37 id={fieldName}
38 ref={inputRef}
39 defaultValue={defaultValue}
40 {...rest}
41 />
42
43 {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'
4
5interface InputProps extends TextInputProps {
6 name: string
7 label: string
8}
9
10interface InputReference extends TextInput {
11 value: string
12}
13
14export default function Input({
15 name,
16 label,
17 onChangeText,
18 ...rest
19}: InputProps) {
20 const inputRef = useRef<InputReference>(null)
21
22 const { fieldName, registerField, defaultValue = '', error } = useField(name)
23
24 useEffect(() => {
25 if (inputRef.current) inputRef.current.value = defaultValue
26 }, [defaultValue])
27
28 useEffect(() => {
29 registerField<string>({
30 name: fieldName,
31 ref: inputRef.current,
32 getValue() {
33 if (inputRef.current) return inputRef.current.value
34
35 return ''
36 },
37 setValue(ref, value) {
38 if (inputRef.current) {
39 inputRef.current.setNativeProps({ text: value })
40 inputRef.current.value = value
41 }
42 },
43 clearValue() {
44 if (inputRef.current) {
45 inputRef.current.setNativeProps({ text: '' })
46 inputRef.current.value = ''
47 }
48 },
49 })
50 }, [fieldName, registerField])
51
52 const handleChangeText = useCallback(
53 (value: string) => {
54 if (inputRef.current) inputRef.current.value = value
55
56 if (onChangeText) onChangeText(value)
57 },
58 [onChangeText]
59 )
60
61 return (
62 <>
63 {label && <Text>{label}</Text>}
64
65 <TextInput
66 ref={inputRef}
67 onChangeText={handleChangeText}
68 defaultValue={defaultValue}
69 {...rest}
70 />
71 </>
72 )
73}
Edit this page on GitHub