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 usingSubmitHandler<FormData>
whereFormData
is the format of data inputted by user; - If you're using
useRef
to access form reference, remember to addFormHandles
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';56interface FormData {7 name: string;8 email: string;9}1011const MyForm: React.FC = () => {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};2526export 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';34interface Props {5 name: string;6 label?: string;7}89type InputProps = JSX.IntrinsicElements['input'] & Props;1011const Input: React.FC<InputProps> = ({ name, label, ...rest }) => {12 const inputRef = useRef<HTMLInputElement>(null);1314 const { fieldName, defaultValue, registerField, error } = useField(name);1516 useEffect(() => {17 registerField({18 name: fieldName,19 path: 'value',20 ref: inputRef.current,21 });22 }, [fieldName, registerField]);2324 return (25 <>26 {label && <label htmlFor={fieldName}>{label}</label>}2728 <input29 id={fieldName}30 ref={inputRef}31 defaultValue={defaultValue}32 {...rest}33 />3435 {error && <span>{error}</span>}36 </>37 );38};3940export 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';45interface InputProps extends TextInputProps {6 name: string;7 label: string;8}910interface InputReference extends TextInput {11 value: string;12}1314const Input: React.FC<InputProps> = ({15 name,16 label,17 onChangeText,18 ...rest19}) => {20 const inputRef = useRef<InputReference>(null);2122 const { fieldName, registerField, defaultValue = '', error } = useField(name);2324 useEffect(() => {25 if (inputRef.current) inputRef.current.value = defaultValue;26 }, [defaultValue]);2728 useEffect(() => {29 registerField<string>({30 name: fieldName,31 ref: inputRef.current,32 getValue() {33 if (inputRef.current) return inputRef.current.value;3435 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]);5152 const handleChangeText = useCallback(53 (value: string) => {54 if (inputRef.current) inputRef.current.value = value;5556 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};7475export default Input;