# Form Use this component when you want to collect input from users. It provides a structure for various input fields and controls, such as text fields, checkboxes, and buttons. It also integrates with the native Contextual Save Bar to handle form submission and reset actions. ### Simple form implementation ```tsx import React, { useCallback, useState } from 'react'; import { reactExtension, Form, TextField, } from '@shopify/ui-extensions-react/admin'; export default reactExtension("admin.product-details.block.render", () => <App />); function App() { const [value, setValue] = useState(""); const [error, setError] = useState(''); const onSubmit = useCallback( async () => { // API call to save the values const res = await fetch('/save', {method:'POST', body: JSON.stringify({name: value})}); if (!res.ok) { const json = await res.json(); const errors = json.errors.join(','); setError(errors); } }, [value] ); const onReset = useCallback(async () => { // Reset to initial value setValue('') // Clear errors setError('') }, []); const onInput = useCallback((nameValue) => { if (!nameValue) { setError("Please enter a name."); } }, []) // Field values can only be updated on change when using Remote UI. const onChange = useCallback((nameValue) => { setValue(nameValue); }, []) return ( <Form id="form" onSubmit={onSubmit} onReset={onReset}> <TextField label="name" value={value} onInput={onInput} onChange={onChange} error={error} /> </Form> ); } ``` ```js import { extend, Form, TextField, } from '@shopify/ui-extensions/admin'; extend('admin.product-details.block.render', (root) => { let name = ''; const textField = root.createComponent( TextField, { label: 'name', value: name, onChange: (value) => { textField.updateProps({value}); name = value; }, } ); const onSubmit = async () => { // API call to save the values const res = await fetch('/save', {method:'POST', body: JSON.stringify({name})}); if (!res.ok) { const json = await res.json(); // The Host can catch these errors and do something with them. throw Error(`There were errors: ${json.errors.join(',')}`); } }; const onReset = async () => { name = ''; }; const form = root.createComponent( Form, {onSubmit, onReset} ); form.appendChild(textField); root.appendChild(form); }); ``` ## FormProps ### FormProps ### id A unique identifier for the form. ### onReset A callback that is run when the form is reset. ### onSubmit A callback that is run when the form is submitted. ## Related - [TextField](/docs/api/admin-extensions/components/forms/textfield) - [NumberField](/docs/api/admin-extensions/components/forms/numberfield) - [EmailField](/docs/api/admin-extensions/components/forms/emailfield)