#form.getInputProps stopping the onChange event

1 messages · Page 1 of 1 (latest)

lethal kelp
#

Hey. Is this supposed to happen? When removingt form.getInputProps it works fine, but adding it stops the onChange even from emitting.

Basically, I have this function which runs whenever the input inside of a mantine <Textarea /> changes, and I need this to run. But it doesn't run when this component is attached to a Mantine useForm.

    return (
    <div className="textAreaContainer">
      <Textarea
        onChange={(event) => {
          console.log(1);
          handleChange(event);
        }}
        styles={(theme) => ({
          input: {
            backgroundColor: theme.colors.dark[9],
          },
        })}
        placeholder={placeHolderText}
        value={settings.newSettings[settingName]}
        maxLength={maxLength}
        autosize={true}
        minRows={2}
        maxRows={5}
        required={required}
        {...form.getInputProps(settingName)}
      />
  )

To attempt to fix this problem I looked at the docs and found the form.isDirty method. However, the problem which this causes is an infinite loop due to the page re-rendering due to my handleChange function updating the state of charCount.

  const handleChange = (value: string) => {
    setCharCount(value.length);
  };

  // when the value for this form element changes
  if (form.isDirty(settingName)) handleChange(form.values[settingName]);

  return (
      <Textarea
        styles={(theme) => ({
          input: {
            backgroundColor: theme.colors.dark[9],
          },
        })}
        placeholder={placeHolderText}
        maxLength={maxLength}
        required={required}
        {...form.getInputProps(settingName)}
      ></Textarea>
somber shell
#

form.getInputProps sets some props to your component to control it, including value and onChange. You don't need to manually specify the onChange event.

If you need a custom onChange event to trigger some additional side-effects, you can achieve this like this:

<Textarea
   // ... Your props
   {...form.getInputProps(settingName)}
   onChange={(e) => {
     // Custom onChange must come after getInputProps spread to replace it
     form.getInputProps(settingName).onChange(e)

     // Do your work here
   }}

However this is not really recommended. A better way would be to have an effect triggered on form.values[settingName] change.

In your case it seems you want to track the length of the current input in a state variable... Why not simply compute it directly?

const charCount = form.values[settingName].length;
lethal kelp
#

Thanks for the advice with the useEffect. This will probably work 🙂

As for storing the charCount in a state variable, the reasoning for this is because I render the charCount on screen whenever the user updates the value inside of the Textarea. Although if I use a useEffect as you suggested I wont need to do that inside of a state var. Thanks for the advice 🙂

somber shell
#

For such trivial computation as <some-string>.length, you don't even need an effect, you can do that directly in the render.

The charCount will get recomputed at every render (but it's very fast), and the component will re-render anyway when the value changes.

So: value change triggers rerender ; char-count computed on render ; char-count will always show up-to-date