React Hook Form: when I render a TextField (materialUI) and provide the Field: {onChange} it says onChange undefined - reactjs

I'm literally following their documentation and also tried the code from an article on github. I have the most recent version installed. Still not working. So frustateeeeeed.
const { control, handleSubmit } = useForm()
This is the component I return:
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="lastName"
control={control}
defaultValue=""
render={({ field, fieldState }) => (
<TextField
label="Last Name"
variant="filled"
value={field.value}
onChange={field.onChange}
error={!!fieldState.error}
helperText={fieldState.error ? fieldState.error.message : null}
/>
)}
rules={{ required: 'Last name required' }}
<Button type="submit" disabled={!stripe} buttonText="Pay"></Button>
</form>
It simply keeps giving the error that field.value, field.onchange, fieldState.error are undefined. I tried destructuring too. Doesn't work either.

Here is a working example: https://codesandbox.io/s/ancient-worker-mdqx3
I recommend passing the ref as well.

Related

React hooks form doesn't accept files, but string to system path instead

I'm trying to load a file using React hooks form and yup, but by wrapping the input type file component in Controller I get instead of the usual Blob, system paths like value
Example of result:
C:\\fakepath\\image.jpeg
Expected result
Blob file
Code example:
Link to sandbox: https://codesandbox.io/s/react-select-with-react-hook-form-forked-4t6ncr?file=/src/App.js
Code:
<form onSubmit={handleSubmit(saveData)}>
{!countryValue && (
<Controller
name="country"
control={control}
render={({ onChange, value, ref }) => (
<Select
options={country}
value={country.find((c) => c.value === value)}
onChange={(val) => onChange(val.value)}
/>
)}
rules={{ required: true }}
/>
)}
{countryValue && (
<Controller
name="country"
control={control}
render={(field) => {
const { onChange } = field;
return <input {...field} type="file" onChange={onChange} />;
}}
rules={{ required: true }}
/>
)}
{errors.country && <div>Field is rquired</div>}
<button type="submit">Save</button>
</form>

react-hook-form with react select

Someone has a working sample with a react-hook-form with a react-select? In below the Select with id="accountId" works. However I need it to be a required field. I tried adding:
innerRef={register({ required: true })}
But that did not work. AFAIK this is because the Select needs to be wrapped in a Controller (correct me if I am wrong).
So I tried adding the Controler where id="accountId2". But now I get error:
Uncaught TypeError: Cannot read property 'split' of undefined
I am looking for a small sample where the Select will be integrated with the form and required fields.
<Container>
<Form onSubmit={handleSubmit(onSubmit)}>
<FormGroup>
<div>
<Controller
as={<Select
name="accountId2"
id="accountId2" />}
options={options}
control={control}
/>
</div>
</FormGroup>
<FormGroup>
<Label for="exampleCheckbox">Choose account to update</Label>
<div>
<Select
name="accountId"
id="accountId"
innerRef={register({ required: true })}
isDisabled={isNewAccount}
ref={selectInputRef}
isClearable={true}
placeholder="Search for an existing account number or click new account below"
label="Single select"
options={options}
defaultValue=""
/>
</div>
Yes, In order for Select to work with RHF, you need to wrap it in a controller like this.
<Controller
as={
<Select>
{options.map((option, index) => (
<MenuItem key={index} value={option}>
{option}
</MenuItem>
))}
</Select>
}
name={options_name}
control={control}
defaultValue=""
rules={{ required: true }}
/>
So it worked for me by adding the following attribute to the controller.
rules={{ required: true }}
Hope this answers your question.
If you are using react-hook-form: "^7.19.1", can be used as below.
<Controller
control={control}
name="test"
render={({
field: { onChange, onBlur, value, name, ref },
fieldState: { invalid, isTouched, isDirty, error },
formState,
}) => (
<Select
onBlur={onBlur}
onChange={onChange}
inputRef={ref}
className={classes.textField}
fullWidth
input={<Input id="name" />}
defaultValue={"science"}
>
{tags.map((tag, index) => (
<MenuItem key={index} value={tag}>
{tag}
</MenuItem>
))}
</Select>
)}
/>

React Hook Form problem with validating using validate function

Hey I'm currently working on validation using customized Antd inputs and React Hook Form.
Currently I have problem with validating fields for URLs (single url and image one) with regex.
I've checked both of regex and they are working
Generally I can't submit the form with correct data, the problem happens within the validation using regex
The form part
<Controller
as={
<InputField
label="URL"
name="url"
placeholder="Enter URL"
error={errors.url}
errorText="URL Error"
/>
}
control={control}
type="text"
name="url"
defaultValue=""
rules={{
validate: (value) => {
return INPUT.urlPattern.test(value);
}
}}
/>
<Controller
as={
<InputField
label="Image Url"
name="imageUrl"
placeholder="enter ImageURL"
error={errors.imageUrl}
errorText="Error on imageUrl"
/>
}
control={control}
type="text"
name="imageUrl"
defaultValue=""
rules={{
validate: (value) => {
return INPUT.imageURLPattern.test(value);
}
}}
/>
Custom antd input component render function
return (
<>
<label className="label" htmlFor={name}>
{label}
</label>
<Styled.Input
placeholder={placeholder}
maxLength={maxLength}
value={value}
onChange={handleInputCounter}
{...(counter
? {
suffix: (
<Styled.WordCounter>
{counterValue} / {maxLength}
</Styled.WordCounter>
)
}
: {})}
/>
{error && <p className="error">{errorText}</p>}
</>
);
I've prepared little demo on codesandbox
https://codesandbox.io/s/react-hook-form-validate-antd-gyhnh?file=/src/EntryForm.tsx

Other validation message is triggering instead of my message when using Ant design getFieldDecorator

I am using Ant design and this is my form when I click on save I am getting this type of validation msg instead of red bordered Antd validation msg
I want validation error like this which is shown in AntD documents.
https://codesandbox.io/s/do52z
I have writter my function like this
<Form id="myForm" onSubmit={this.handleSubmit}>
<Form.Item label="Code">
<CustomInput
form={this.props.form}
type="text"
disabled={this.state.disableFields}
name="code"
id="code"
placeholder=""
required={true}
errorMsg={"Please input code!"}
/>
</Form.Item>
</Form>
This is my custom Input
const CustomInput = ({
form, id, name, placeholder, required, errorMsg, type, disabled,}: Props) => {
return form.getFieldDecorator(id, {
rules: [
{
required: required,
message: errorMsg
}
]
})(
<Input
type={type}
name={name}
id={id}
disabled={disabled}
placeholder={placeholder}
className={name === "code" ? "code-input" : "input-box"}
/>
);
};
export default CustomInput;
and this is my save button
<Button
className="save-btn"
htmlType="submit"
form="myForm"
>
Save
</Button>
I think I am missing something little here. Thanks in advance
Ant design input doesn't have required prop..
Required prop should be give inside form.item rules prop.
Since you have given reqired to input tag it will cause Chrome to display a prompt that the user to fill out the field.
Update based on comment
Move formitem tag inside custominput component and try again.
<Form id="myForm" onSubmit={this.handleSubmit}>
<CustomInput
form={this.props.form}
type="text"
disabled={this.state.disableFields}
name="code"
id="code"
placeholder=""
required={true}
errorMsg={"Please input code!"}
/>
</Form>
..
const CustomInput = ({
form, id, name, placeholder, required, errorMsg, type, disabled,}: Props) => {
return(
<Form.Item label="Code">
{form.getFieldDecorator(id, {
rules: [
{
required: required,
message: errorMsg
}
]
})(
<Input
type={type}
name={name}
id={id}
disabled={disabled}
placeholder={placeholder}
className={name === "code" ? "code-input" : "input-box"}
/>
)}
</Form.Item>
)
};

why is first letter dead in react-hook-form input

i need help to understand why the first letter in the simple input component is not registered.
I've created a simple controlled input from the examples but its not working properly.
i created an example for you https://stackblitz.com/edit/react-9zezqx
const App = () => {
const { register, handleSubmit, watch, errors, reset, control, formState } = useForm({ mode: 'onChange' });
console.log(errors)
return (
<div>
<form onSubmit={handleSubmit(() => console.log("submit"))}>
<Controller
as={TextInput}
name="firstname"
defaultValue=""
control={control}
inputRef={register({ required: true, minLength: 8 })}
hasErrors={errors.firstname !== undefined}
/>
<br/>
<Controller
as={TextInput}
name="hobby"
defaultValue=""
control={control}
inputRef={register({ required: true, minLength: 8 })}
hasErrors={errors.hobby !== undefined}
/>
</form>
</div>
);
}
render(<App />, document.getElementById('root'));
import * as React from 'react';
export const TextInput = (props) => {
return(
<>
<input
type="text"
name={props.name}
value={props.value}
onChange={props.onChange}
ref={props.inputRef}
/>
{props.hasErrors && (<h2>errors!!</h2>)}
</>
)
}
okay i found the bug causing it in 'onBlur' aswell
reValidateMode: 'onBlur'
Swap the mode to onBlur, this will improve the performance, will trigger only when the user leaves the field, which is suppose to happen, and also does not swallow the first input.
onChange skips the first letter, because the default value will be used for the initial onChange call, which is empty.
You are probably using an uncontrolled input. If that's the case use defaultValue instead of value.
Reference
This is the problem here, you are try to use Controller with register:
https://react-hook-form.com/api#Controller
<Controller
as={TextInput}
name="hobby"
defaultValue=""
control={control}
/>
or
https://react-hook-form.com/api#register
<TextInput inputRef={register} />

Resources