react-final-form-listeners icon indicating copy to clipboard operation
react-final-form-listeners copied to clipboard

OnChange function is called on every render instead of user interaction.

Open pandey-sid opened this issue 5 years ago • 4 comments

Are you submitting a bug report or a feature request?

bug report

What is the current behavior?

I’m using this inside a field array, I basically want to reset an input text field on change of a dropdown/select field item. It works fine as expected. But when I delete that row, the field-array template is re-rendered that causes the onChange of the dropdown in each row to execute again that resets the other selections made by the user.

What is the expected behaviour?

The expected behaviour is that the onChange handler should only be called when a user performs a change to the input/select. It shouldn't be called by re-render of FieldArray.

I've followed the example that is mentioned here: It says that "It’s important to notice that the function given to OnChange will only be called when the value changes, not on every render."

Sandbox Link

What's your environment?

"react": "^16.3.2", "react-apollo": "^2.3.1", "react-beautiful-dnd": "^9.0.2", "react-dom": "^16.3.2", "react-final-form": "^3.6.2", "react-final-form-listeners": "^1.0.1", "react-final-form-arrays": "^1.0.6" Mac - Chrome Browser Version 70.0.3538.110 (Official Build) (64-bit)

pandey-sid avatar Dec 12 '18 12:12 pandey-sid

Sandbox link @pandey-sid ?

HawiCaesar avatar Dec 18 '18 15:12 HawiCaesar

Having this issue too

JackHowa avatar Sep 04 '19 16:09 JackHowa

This was helpful fix for me, using the previous param:

import { Field } from 'react-final-form';
import { OnChange } from 'react-final-form-listeners';

// based off of library author https://medium.com/@erikras/declarative-form-rules-c5949ea97366
const WhenFieldChanges = ({ field, set, to }) => (
  <Field name={set} subscription={{}}>
    {({ input: { onChange } }) => (
      <OnChange name={field}>
        {(value, previous) => {
          // prevent on render issue changing the field
          if (previous !== '') {
            onChange(to);
          }
        }}
      </OnChange>
    )}
  </Field>
);

export default WhenFieldChanges;

JackHowa avatar Sep 04 '19 16:09 JackHowa

This was helpful fix for me, using the previous param:

import { Field } from 'react-final-form';
import { OnChange } from 'react-final-form-listeners';

// based off of library author https://medium.com/@erikras/declarative-form-rules-c5949ea97366
const WhenFieldChanges = ({ field, set, to }) => (
  <Field name={set} subscription={{}}>
    {({ input: { onChange } }) => (
      <OnChange name={field}>
        {(value, previous) => {
          // prevent on render issue changing the field
          if (previous !== '') {
            onChange(to);
          }
        }}
      </OnChange>
    )}
  </Field>
);

export default WhenFieldChanges;

How would you do this if you want the field change to display a FieldArray (Push one to a FieldArray since the componentDidMount() has issues with initialising one item in the array)

Hyokune avatar Nov 09 '20 23:11 Hyokune