Unform

Usage with TypeScript

Usage with TypeScript

Unform exposes all type definitions from within it's packages, so it's not necessary 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 user;
  • If you're using useRef to access form reference, remember to add FormHandles as 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
11const MyForm: React.FC = () => {
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};
25
26export default MyForm;

Simple input (ReactJS)

When creating a simple HTML input or any other HTML element used for input source, remember to always extend the element props. In web you can always use the JSX.IntrinsicElements['element'] to get the props adapted to JSX.

Also, in web (ReactJS) remember to 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
11const Input: React.FC<InputProps> = ({ name, label, ...rest }) => {
12 const inputRef = useRef<HTMLInputElement>(null);
13
14 const { fieldName, defaultValue, registerField, error } = useField(name);
15
16 useEffect(() => {
17 registerField({
18 name: fieldName,
19 path: 'value',
20 ref: inputRef.current,
21 });
22 }, [fieldName, registerField]);
23
24 return (
25 <>
26 {label && <label htmlFor={fieldName}>{label}</label>}
27
28 <input
29 id={fieldName}
30 ref={inputRef}
31 defaultValue={defaultValue}
32 {...rest}
33 />
34
35 {error && <span>{error}</span>}
36 </>
37 );
38};
39
40export default Input;

Simple input (React Native)

Let's create an InputProps interface for the component. In addition, 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
14const Input: React.FC<InputProps> = ({
15 name,
16 label,
17 onChangeText,
18 ...rest
19}) => {
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};
74
75export default Input;
Edit this page on GitHub