Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Formik.submitForm() calls setState() when unmounted if validation fails #854

Closed
chasecaleb opened this issue Aug 27, 2018 · 1 comment
Closed

Comments

@chasecaleb
Copy link

Current Behavior

If a form is submitted and validation fails, Formik calls setState() to record the validation failure. This happens even if the component is unmounted, which triggers a console warning from React.

Similar issues were discussed in #597. PR #756 fixed other situations where this can occur, but I think overlooked this edge case.

Steps to Reproduce

  1. Submit form, which calls Formik.submitForm()
  2. submitForm() starts async validation
  3. Formik component unmounts (caused by a parent component unmounting)
  4. submitForm() calls setState() to reflect that validation failed.

Console warning:

Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
    in Formik (created by [my app component])
    in [snipped - bunch of my own components]
__stack_frame_overlay_proxy_console__ @ index.js:2178
printWarning @ warning.js:33
warning @ warning.js:57
warnAboutUpdateOnUnmounted @ react-dom.development.js:15206
scheduleWork$1 @ react-dom.development.js:16227
enqueueSetState @ react-dom.development.js:11300
./node_modules/react/cjs/react.development.js.Component.setState @ react.development.js:270
(anonymous) @ formik.esm.js:264
Promise.then (async)
Formik._this.submitForm @ formik.esm.js:258
(anonymous) @ selectLicenses.tsx:40
callCallback @ react-dom.development.js:100
invokeGuardedCallbackDev @ react-dom.development.js:138
invokeGuardedCallback @ react-dom.development.js:187
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:201
executeDispatch @ react-dom.development.js:461
executeDispatchesInOrder @ react-dom.development.js:483
executeDispatchesAndRelease @ react-dom.development.js:581
executeDispatchesAndReleaseTopLevel @ react-dom.development.js:592
forEachAccumulated @ react-dom.development.js:562
runEventsInBatch @ react-dom.development.js:723
runExtractedEventsInBatch @ react-dom.development.js:732
handleTopLevel @ react-dom.development.js:4477
batchedUpdates$1 @ react-dom.development.js:16660
batchedUpdates @ react-dom.development.js:2131
dispatchEvent @ react-dom.development.js:4556
interactiveUpdates$1 @ react-dom.development.js:16715
interactiveUpdates @ react-dom.development.js:2150
dispatchInteractiveEvent @ react-dom.development.js:4533

Expected behavior

No warning from React.

Suggested solution(s)

Fortunately easy. Modify this section of Formik.submitForm():

formik/src/Formik.tsx

Lines 426 to 433 in a35fba4

return this.runValidations().then(combinedErrors => {
const isValid = Object.keys(combinedErrors).length === 0;
if (isValid) {
this.executeSubmit();
} else {
this.setState({ isSubmitting: false });
}
});

Specifically, check this.didMount before calling setState() on line 431, as is done in other parts of this component.

Don't have a minimal CodeSandbox repro, but I think the issue is still clear without one.


  • Formik Version: 1.1.1
  • React Version: 16.4.2
  • TypeScript Version: 3.0.1
  • Browser and Version: Chrome stable - 69
  • OS: Windows 10
  • Node Version: 10.3.0
  • Package Manager and Version: yarn 1.9.4
@jaredpalmer
Copy link
Owner

Good looks. Will tweak.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants