robster
robster

Reputation: 656

react-hook-form controller with materialUI TextField form results in a TypeError: e.target is undefined when using onChange

I've come across something interesting and would like to ask for some help.

I keep getting an error TypeError: e.target is undefined when trying to do an onChange.

I have a setup similar to this:

import React, { useEffect, useState } from "react";
import { useForm, Controller } from "react-hook-form";
import Grid from "@material-ui/core";

import TextField from "@material-ui/core/TextField";

export default function LogInForm() {
    const [userName, setUserName] = useState("asdf");

    const { register, handleSubmit, control, errors } = useForm();

    const updateUserName = (e) => {
    setUserName(e.target.value);
    };

    const onSubmit = (data) => {
    console.log(data);
    };

    return (
    <form className={classes.form} onSubmit={handleSubmit(onSubmit)}>
        <Grid container spacing={3}>
        <Grid item xs>
            <Controller
            as={<TextField />}
            name="user_name"
            label="Username"
            control={control}
            value={userName}
            variant="outlined"
            margin="normal"
            required
            fullWidth
            id="user_name"
            autoComplete="Username"
            autoFocus
            // onChange={(e) => setUserName(e.target.value)}
            // onChange={([e]) => setUserName(e.value)}
            onChange={updateUserName}
            />
        </Grid>
        </Grid>
        </form>
    )
}

You'll notice a couple of commented out attempts on the onChange. ALL three of these come up with the same error TypeError: e.target is undefined.

Now I can only assume this is due to the react-hook-form using the Controller to wrap the TextField?

How can I still do an onChange, to change the state in this example? I've spent some hours on this but have come to a wall and any advice would be greatly appreciated.

Thank you.

UPDATE: In response to a test request I added:

const updateUserName = (e) => {
    console.log(e);
    setUserName(e.target.value);
    console.log(e);
};

This resulted in an empty array in the console.

Upvotes: 1

Views: 5941

Answers (3)

KanerA
KanerA

Reputation: 1

You should try passing the options object to the use form and setting the mode to onChange so that the controller will get the current value, because the default is onSubmit.

const { register, handleSubmit, control, errors } = useForm({ mode: 'onChange'})

Upvotes: 0

Deepak Singh
Deepak Singh

Reputation: 650

Can you please try it like this!

<Controller
  as={<TextField />}
  name="user_name"
  label="Username"
  control={control}
  value={userName}
  variant="outlined"
  margin="normal"
  required
  fullWidth
  id="user_name"
  autoComplete="Username"
  autoFocus
  onChange={([ event ]) => {
    updateUserName(event)
    return event.target.value
  }}
/>

And then your updateUserName will listen to the changes as you have already written.

const updateUserName = (e) => {
  console.log(e.target.value)
  setUserName(e.target.value);
};

Upvotes: 3

Yoandry Collazo
Yoandry Collazo

Reputation: 1212

Cloud you check this React-Form-Hook Controller Docs

   onChange={{([ event ]) => event.target.value}}
onChange={{([ { checked } ]) => ({ checked })}}

Check this example using onChange Example using onChange

Upvotes: 0

Related Questions