Support Uncontrolled Components in User Inputs (Checkbox, Radio, Input, etc.) #1111
-
The value component is always required for Inputs. This is a completely fine approach when we expect all inputs to be a controlled component type. Since this is a general Component library I feel it should also support the uncontrolled type of component. My personal use case and some others in the org are the use of the library It generally wants to work like... // From https://react-hook-form.com/get-started
export default function App() {
const { register, handleSubmit, watch, errors } = useForm();
const onSubmit = data => console.log(data);
console.log(watch("example")); // watch input value by passing the name of it
return (
{/* "handleSubmit" will validate your inputs before invoking "onSubmit" */}
<form onSubmit={handleSubmit(onSubmit)}>
{/* register your input into the hook by invoking the "register" function */}
<input name="example" defaultValue="test" ref={register} />
{/* include validation with required or other standard HTML validation rules */}
<input name="exampleRequired" ref={register({ required: true })} />
{/* errors will return when field validation fails */}
{errors.exampleRequired && <span>This field is required</span>}
<input type="submit" />
</form>
);
} You use the useForm hook to create a register function which works against the name and ref of input fields. The register function then attaches to the onChange/Focus/blur/value of the html element. With the current implementation of Input the recommended approach is to use the libraries Controller HOC. My implementation is as follows. // Based on -- https://react-hook-form.com/get-started#IntegratingControlledInputs
export default function Home() {
const { register, handleSubmit, watch, errors, control } = useForm();
const onSubmit = (data) => console.log(data);
// console.log(watch("example")); // watch input value by passing the name of it
return (
<div>
<Controller
id="Name"
name="Name"
control={control}
rules={{ required: "Yo this is very required" }}
defaultValue=""
render={(props) => {
const hasError = errors.Name;
return (
<>
<Input
id="Name"
name="Name"
type="text"
value={props.value}
onChange={props.onChange}
hasError={hasError}
/>
{hasError && (
<HelpText variant="error">{errors.Name.message}</HelpText>
)}
</>
);
}}
/>
</div>
)
} Other people are looking to use this form lib and have generated special ways to fix this. Primarily by removing the required value field in Typescript and just ignoring the errors generated by the propTypes library. Ex // https://github.com/vnguyen94/react-hook-form-paste
Example From the Input file
//https://github.com/vnguyen94/react-hook-form-paste/blob/main/src/components/Input/Input.tsx
import * as React from 'react';
import { Input as $Input, InputProps as $InputProps } from '@twilio-paste/core/input';
import { FieldValues } from 'react-hook-form';
export function Input<TKeys extends FieldValues>(
props: Omit<$InputProps, 'ref' | 'onChange' | 'value'> &
Partial<Pick<$InputProps, 'onChange' | 'value'>> & {
registerRef: React.Ref<HTMLInputElement>;
name: keyof TKeys;
},
): React.ReactElement {
const { registerRef: ref, ...rest } = props;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return <$Input ref={ref} {...rest} />;
}
Input.displayName = 'Input'; Generally it seems this component works fine if we ignore the safeguards and we get the intended functionality so we should remove the safeguard or provide an alternative Input component without those type restrictions (My money is just changing the props for the currently existing component) |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 4 replies
-
+1 for components that are closer to native HTML components (no required fields). another thought i had was adding a discriminated prop e.g. |
Beta Was this translation helpful? Give feedback.
-
Thanks for the reporting this. I can see the value in having this functionality, so I've added a ticket to our backlog to fix it. Will report back when it's merged. |
Beta Was this translation helpful? Give feedback.
Thanks for the reporting this. I can see the value in having this functionality, so I've added a ticket to our backlog to fix it. Will report back when it's merged.