final-form / final-form/react-final-form

FormSpy.onChange callback unable to use closure over state reference

Open
#671 4 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
7.4k
Forks
497
PR merge metrics
No merged PRs in 30d

Description

### Are you submitting a **bug report** or a **feature request**?

Bug report

### What is the current behavior?

In a functional component using `useState` hooks, callbacks passed to `FormSpy.onChange` which enclose state values only see the initial value of the state -- in other words, the `onChange` handler gets stale state values.

### What is the expected behavior?

When passing a callback to `FormSpy.onChange`, it should behave like `` with respect to enclosed state values, and have access to the current value of enclosed vars.

### Sandbox Link

https://codesandbox.io/s/react-final-form-loading-and-initializing-9h1gn

This example presents two input controls. The first one is a simple ``, which fetches the current time when a character in the input box is changed.

The second input control is within a React Final Form `Field`. `` fetches the current time when the second input is changed.

The behavior of these two `onChange` handlers differs: the plain `` encloses the current value of the `time` state var. The FormSpy-based variant, however, does not; and only has access to the initial value of state.

### What's your environment?

- final-form: 4.12.0
- react: 16.8.6
- react-dom: 16.8.6
- react-final-form: 5.0.1

### Other information

This behavior may be related to the specific way that the `useFormState` hook wraps the `onChange` call in `useEffect`. I can achieve similarly pathological behavior in the simple `input.onChange` handler if I define the handler with `useCallback` to prevent updates to the function:

```
const fetchTime = useCallback(() => {
setWithinFetchTimeFunc(time);
fetch("https://worldtimeapi.org/api/timezone/America/Denver")
.then(res => res.json())
.then(json => setTime(json.utc_datetime))
}, []);
```

this leads me to believe that the similar [`useEffect`](https://github.com/final-form/react-final-form/blob/3634b35cfe63511c221b13d64699b0a53035142f/src/useFormState.js#L32-L46) construct may be suppressing changes to the `onChange` function.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.