Future Export: the useControl hook
#962
Replies: 3 comments 10 replies
-
|
Hi, thank you or the amazing library and all the work you do! In our project we were already using I know I probably shouldn't have relied on the unstable API 😅 in the first place but I liked this API a lot. What is the plan for |
Beta Was this translation helpful? Give feedback.
-
|
Is |
Beta Was this translation helpful? Give feedback.
-
|
I tried to use select from react-aria example ( https://github.com/edmundhung/conform/blob/main/examples/react-aria/src/components/Select.tsx) and it returns onValidate the last value only. <>
<select name={name} ref={control.register} hidden>
<option />
</select>
<Select
selectedKeys={control.options}
onSelectionChange={(keys) => {
const selection = keys as Set<string>;
control.change(Array.from(selection));
}}
description={description}
isDisabled={disabled}
isRequired={field.required}
errorMessage={errorMessage}
isInvalid={isInvalid}
variant="bordered"
listboxProps={{
emptyContent: "Нічого не знайдено",
}}
label={label}
placeholder={placeholder}
selectionMode="multiple"
>
{options.map((option) => (
<SelectItem key={option.value} textValue={option.label}>
{option.label}
</SelectItem>
))}
</Select>
</> |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
The
useControlhook is an experimental API released under thefutureexport. It's designed to address the limitations ofuseInputControl, which works well for simple cases — but gets in the way for dynamic or custom UI components.useInputControlautomatically renders a hidden input for you, which makes it feel familiar to developers coming from traditional form libraries. But this abstraction has trade-offs:useControlis a successor to the previously undocumentedunstable_useControlhook. It gives you full control over how the base input is rendered and connected to Conform. You render the input, register it manually, and decide how and when to sync its state — while still benefiting from validation, metadata, and native event handling.The UI Libraries Integration Guide has also been updated with practical tips and examples for working with
useControl. For more details on the API itself, see theuseControlAPI reference.What's changed
Manual input registration with full control
Unlike
useInputControl,useControldoesn't render an input for you — you render and register the input manually. This gives you full control and avoids the limitations of automatic rendering.You are required to manage the base input, but the
useControlhook helps simplify the setup — more so thanunstable_useControldid:defaultValue(ordefaultChecked) touseControl, and it will apply it when the input is first registered. If you're rendering your form server-side, you should still set the default value directly on the input if you care about the initial value before JavaScript loads.hidden. If you want to delegate focus to a custom input component, set anonFocushandler in the options. Conform will automatically apply the necessary accessibility attributes, includingaria-hidden,tabIndex={-1}, andstylerules to make the hidden input focusable but invisible to screen readers.New field metadata for default values
To simplify integration, each field now includes default-related metadata:
defaultValuefor text input, single radio button or single selectdefaultOptionsfor multi-select or checkbox groupsdefaultCheckedfor single checkboxThese values are computed automatically from your form's
defaultValue:They make it easier to pass the correct values when initializing
useControl.Refined control value
useControlexposes a set of properties for working with various input types:control.valueCurrent value of the base input. Undefined if the registered input is a multi-select, file input, or checkbox group.
control.optionsSelected options of the base input. Defined only when the registered input is a multi-select or checkbox group.
control.checkedChecked state of the base input. Defined only when the registered input is a single checkbox or radio input.
control.filesSelected files of the base input. Defined only when the registered input is a file input.
Group registration for checkbox or radio
You can register multiple checkbox or radio inputs as a group by passing an array of elements to
register(). This is useful when the setup renders a set of native inputs that you want to re-use without re-implementing the group logic:If you don't need to re-use the existing native inputs, you can always represent the group with a single hidden multi-select or text input.
For complete examples, see the checkbox and radio group implementations in the React Aria example.
Examples
We've prepared examples for integrating with popular UI libraries, including a new example with React Aria components:
If the library you're using isn't listed or you run into issues, open a discussion — we're happy to help. Contributions are also welcome if you'd like to share an example.
Beta Was this translation helpful? Give feedback.
All reactions