question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

input.onChange has a new reference each time value changes

See original GitHub issue

Are you submitting a bug report or a feature request?

Bug report

What is the current behavior?

Every time a field value changes, onChange gets a new reference (and maybe other event handlers do as well).

What is the expected behavior?

When building a custom field and using useEffect, it’s frequent to depend on onChange to update a value. In my case for a large field, I use useMemo to make sure I only rerender the parts that need it, but onChange makes sure everything gets updated every time the value changes. Is there another way than useCallback(input.onChange, [])?

Sandbox Link

https://codesandbox.io/s/react-final-form-third-party-components-example-lo4yo?file=/index.js

What’s your environment?

(Latest on every lib, as seen on the sandbox)

Other information

/

Thanks in advance!

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:4
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
erikrascommented, Jul 21, 2021

Here’s a test I wrote when investigating this. Please include it in the PR.

  it('should give same instance of handlers as value changes', () => {
    const spy = jest.fn()
    const MyField = ({ name }) => {
      const { input } = useField(name, { subscription: { value: true } })
      const { onChange, onFocus, onBlur } = input
      spy(onChange, onFocus, onBlur)
      return <input {...input} />
    }
    render(
      <Form onSubmit={onSubmitMock}>
        {() => (
          <form>
            <MyField name="myField" />
          </form>
        )}
      </Form>
    )

    expect(spy).toHaveBeenCalledTimes(2)
    const [onChange, onFocus, onBlur] = spy.mock.calls[1]
    const setValue = value => {
      act(() => {
        onFocus()
        onChange(value)
        onBlur()
      })
    }
    setValue('dog')
    expect(spy).toHaveBeenCalledTimes(3)
    expect(spy.mock.calls[2][0]).toBe(spy.mock.calls[1][0]) // onChange
    expect(spy.mock.calls[2][1]).toBe(spy.mock.calls[1][1]) // onFocus
    expect(spy.mock.calls[2][2]).toBe(spy.mock.calls[1][2]) // onBlur
    setValue('cat')
    expect(spy).toHaveBeenCalledTimes(4)
    expect(spy.mock.calls[3][0]).toBe(spy.mock.calls[1][0]) // onChange
    expect(spy.mock.calls[3][1]).toBe(spy.mock.calls[1][1]) // onFocus
    expect(spy.mock.calls[3][2]).toBe(spy.mock.calls[1][2]) // onBlur
    expect(spy.mock.calls[3][0]).toBe(spy.mock.calls[2][0]) // onChange
    expect(spy.mock.calls[3][1]).toBe(spy.mock.calls[2][1]) // onFocus
    expect(spy.mock.calls[3][2]).toBe(spy.mock.calls[2][2]) // onBlur
  })
2reactions
erikrascommented, Jul 21, 2021

we guarantee that identity of the methods are stable from the very start, the same way react guarantees that dispatch or setState identity is preserved throughout rerenders.

That’s the winning argument, I think. Callbacks a library gives you should be instance-stable across renders.

This will be a breaking change. @kapral18, can you PR this change?

Read more comments on GitHub >

github_iconTop Results From Across the Web

ReactJs: Input onChange requires to be updated each time to ...
And the problem I am facing is that I have to enter a value into input field by click or selecting the input...
Read more >
HTMLElement: change event - Web APIs | MDN
The change event is fired for , , and elements when the user modifies the element's value. Unlike the input event, the change...
Read more >
oninput Event - W3Schools
This event occurs when the value of an <input> or <textarea> element is changed. Tip: This event is similar to the onchange event....
Read more >
Input.onchange - JavaScript: The Definitive Guide, Fourth ...
The onchange property of an Input object specifies an event handler function that is invoked when the user changes the value displayed by...
Read more >
lightning-input - documentation - Salesforce Developers
You can define an action for input events like blur , focus , and change . For example, to handle a change event...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found