๐Origin
This PR is led by a TS bug #1580 where required props will require to fulfill again at the props
.
Example CSB: https://codesandbox.io/s/react-hook-form-controller-template-qrtco
type MyInputProps = {
value: any;
onChange: () => void;
};
function MyInput(props: MyInputProps) {
return <input name="FirstName" {...props} />;
}
<Controller
as={<input name="FirstName" />} // result in TS error for required onChange and value
defaultValue="FirstName"
control={control}
/>
โ๏ธSolutions
Render prop was purposed by @kotarella1110 which also lead to a discussion around shaping better API. Here are the options
OPTION A only support Render Props for Controller
cons:
- verbose for simple usage
- impact API consistency between
ErrorMessage
and Controller
pros:
- consistent usage with Controller
- less code inside lib
- predictable result
OPTION B support both as
and render
cons:
- less intuitive consider providing two options:
as
vs render
. this could lead to confusion.
- lack of consistent usage
pros:
- consistent API across
ErrorMessage
& Controller
- more code inside lib
- simple usage option, plug-in & play
- the community seems to be keener with both options
โ OPTION C render
support render props and component
This approach having issues with good/easy TS
support and having issue useFieldArray
(which lead input to remount)

๐งPoll result
The above options lead us into discussion and poll on twitter. Below is a good result.

๐ฆWhat's next?
The plan is to release an RC.2 version with option B and waiting for the community's feedback for 2 weeks before releasing the new V6. During the period, if users raise concerns over the new API and we will re-look at option A again.
๐Changes
Less of a breaking change for existing users, simple usage remain while still give the user the full control with render prop. Remove the following props
onChange
onChangeName
onBlur
onBlurName
valueName
Simple usage as below, will not be impacted:
<Controller as={TextField} control={control} name="test" />
Usage involed configration and those remmoved props:
-<Controller
- as={CustomInput}
- valueName="textValue"
- onChangeName="onTextChange"
- control={control}
- name="test"
-/>
+<Controller
+ render={({ onChange, onBlur, value }) => (
+ <CustomInput onTextChange={onChange} onBlur={onBlur} textValue={value} />
+ )}
+ control={control}
+ name="test"
+/>
change render props from children
to render
, usage change from the ability to use both to either. you can either use as
or render
. for multiple error messages, you will have to use render
<ErrrorMessage errors={errors} as="p" />
<ErrrorMessage errors={errors} render={({message}) => {message}} />
Note: Both ErrorMessage
and Controller
contains as
and render
props. Users should either use as
or render
.
โ<Controller as={TextField} render={(props) => <TextField {...props} />}/>
โ<ErrorMessage as={TextField} render={({ message }) => {message} }/>
โ
<Controller as={TextField} />
โ
<Controller render={(props) => <TextField {...props} />}/>
โ
<ErrorMessage as={TextField} />
โ
<ErrorMessage render={({ message }) => {message} }/>