Formik: FastField does not register user input in React 16.4

Created on 27 May 2018  路  7Comments  路  Source: formium/formik

Describe the bug
FastField does not register the changed value when entering text into an input.

To Reproduce
https://codesandbox.io/s/o52powyy69

Expected behavior
As a user, when I enter text into the textbox, the text should appear in the box.

Suggested solution(s)

Additional context
This appears to be related to the change in getDerivedStateFromProps where now it is triggered on every render. https://reactjs.org/blog/2018/05/23/react-v-16-4.html#bugfix-for-getderivedstatefromprops

  • Formik Version: 1.0.0-beta.2
  • React Version: 16.4.0
  • TypeScript Version: 2.8.3
  • CodeSandbox Link: https://codesandbox.io/s/o52powyy69
  • OS: N/A
  • Node Version: N/A
  • Package Manager and Version: N/A

Most helpful comment

@prichodko would love to see that in a proof of concept in a codesandbox

All 7 comments

Confirming the same behavior since updating to React 16.4.
This means that all fields that rely on FastField show up as read-only with the current version of React.

/cc @jaredpalmer as this is quite a serious thing :)

Just wanted to add to @eugene1g comment above - the typed value is being written to the field but it is being overwritten/cleared after getDerivedStateFromProps executes.

Can someone submit a PR?

crickets

I think the behavior of FastField will be highly complex because it hits against two of the trickiest parts of API: choosing props vs state, and syncing uncontrolled components to the master state.

The naive PR would be to pick the local state value, but that would introduce a new subtle bug that if the value is updated elsewhere in Formik, the input text shows in FastField will be out of date. A less naive PR would capture the original passed value, and do a 3-way comparison between "original / state / latest prop", but then we're getting into conflict resolution.

(related discussions: https://github.com/facebook/react/issues/12898#issuecomment-392117539 and https://github.com/facebook/react/issues/12898#issuecomment-392035163 )

As FastField is such a core component, and any changes to it could be volatile, I see this as an architecture-level decision/PR and I definitely don't understand Formik goals/roadmap well enough to make a useful suggestion.

After reading the thread and especially comments from @bvaughn (https://github.com/facebook/react/issues/12898#issuecomment-392266811) and @gaearon (https://github.com/facebook/react/issues/12898#issuecomment-392345559) - which was enlightening 馃槃, I think it's now more important then ever to properly differentiate between controlled and uncontrolled components.

The reason why FastField exists is because we needed an _uncontrolled_ component to prevent unnecessary renders. When we are trying to sync it with a parent (parent <- child relationship) we are using a prop (which is correct), but when we are trying to sync it (parent -> child) we let children to decide how to do that (which is wrong, because children usually don't have enough context to decide).

Proposed solution

I think uncontrolled children should register it's ref to a parent (we now register it using name) and expose instance methods to adjust it's behavior (reset, setError, setValue) and let parent decide when to call it (similarly to how reset works right meow).

I can send a PR.

@prichodko would love to see that in a proof of concept in a codesandbox

Forked sandbox with 1.0.0-beta.4 which appears to work now: https://codesandbox.io/s/889vlp6rl0

Was this page helpful?
0 / 5 - 0 ratings