All of the above. Maybe there is a better way to do what I'm trying to do, which is wrap a material-ui component with a formik Field. =) In my own code, I use a nice re-usable component and TypeScript. I tried to simplify things here.
Please see the codesandbox: https://codesandbox.io/s/21jowlv4p
Since it is timing related (depends on when the promise executes), if you don't see the error, click the reload button in the sandbox and try again.
There doesn't seem to be an easy way to hook into the promise of validateYupSchema. It resolves after the modal is closed and therefore the component has already unmounted and the setState call fails.
Using a promise like this doesn't seem like a good idea since promises really should be chained to ensure execution order. Given that onSuccess() could be null as well, that also seems dangerous.
validateYupSchema(values, schema).then(
() => {
this.setState({ errors: {} });
if (onSuccess) {
onSuccess();
}
},
(err: any) =>
this.setState({ errors: yupToFormErrors(err), isSubmitting: false })
);
https://github.com/jaredpalmer/formik/blob/master/src/Formik.tsx#L390
Thus, this error:
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.
No errors.
I'm not quite sure yet. I'd say start with doing that promise in another way.
One 'workaround' is to validateOnBlur={false} on the <Formik /> element. This prevents the double validation from happening. However, it still kind of leaves a mess. Hard to write a codesandbox.io, but the MUI <Button /> I use for opening my modal, oddly doesn't finish its transition when blur is false.
The more I think about this, the more I wish onSubmit() returned a promise that resolved after all the internal formik stuff resolved. onSubmit( setState() ).then( closeModal )
It's because the yup validations are done in a promise and when the promise resolves it calls setFormikState which calls this.setState(s, callback); without checking if the component is still mounted: https://github.com/jaredpalmer/formik/blob/0b8346d302e71515b8cd987e528908003e0145f6/src/FastField.tsx#L225
Yup (literally)! There is also a double validation run. Blur and Change happen at the same time. Would be nice to find a way to suppress that since the only outcome is a submit in this case.
@jaredpalmer Ping.
This bothers me as well. Thinking about other solutions than using conditionals which decide whether component is about to unmount...
I updated the dependencies in the codelink to the latest versions. It would be nice if @jaredpalmer would comment on this. Happy to work on a PR if I had some direction from him.
I have the same type of problem. I'm using a form in a popup that I close in my submitHandle's function success callback.
The workaround I have for now is to delay closing the popup for 200 ms in addition to preventing validation on blur as @lookfirst mentionned. Not pretty, but avoids the error for now. I'd be glad to have a more permanent fix, since validation on blur is quite useful for UX.
const formikOptions = {
mapPropsToValues: () => defaultValues,
validationSchema: schema,
handleSubmit({ name }, { props, resetForm }) {
myMethod({ name }, uiCbHndl({
onSuccess: () => setTimeout(props.closePopup, 200),
onEnd: () => resetForm(),
}));
},
validateOnBlur: false,
};
personnally I have solved this error message with writing handlesubmit like that
handleSubmit: async (payload, { props }) => {
await console.log(payload);
props.closeWindow();
},
@sohuman Thanks for the comment, but I don't see how making handleSubmit as async would solve this issue. Can you please give more insight?
you're true, it was time for me to sleep yesterday :-p
it makes no sense to async handleSubmit.
I had done some other modifications between to do this (I haven't refreshed my window) :-/ ...
You can solve this with doing your SetState with an arrow function.
handleSubmit: (payload, { props }) => {
props.closeWindow();
},
and in your parent component :
closeWindow() {
return () => this.setState(....)
}
@sohuman Sorry mate, not sure how that solves the issue of not being able to access the promise returned from validateYupSchema().
I'm seeing this when trying to navigate using react-router-dom in handleSubmit. If I put history.push in a setImmediate callback I can get around the problem. It almost seems like we need an afterSubmit handler or something.
I've solved my problem using this:
```
state = {
isMounted: false,
};
componentDidMount() {
this.setState({ isMounted: true }, () => {
if (this.state.isMounted) {
this.setState({ isMounted: false });
{
// do something
// this.props.onClick(...)
}
}
});
}
fxiing this as we speak.
Actually found a different bug, but I (think) i know how to fix this too.
PSA. BE CAREFUL WITH REACT HELMET and 16.4. We've spent last 5 hours trying to debug what we thought was a formik error, but it was actually React Helmet calling deep-equal on a HUGE ASS tree.
I don't use helmet, so I'm not sure how that applies here, but sorry for your pain. ;-)
Yup I figured it out (i think).
@lookfirst Built a demo of how the PR works here: https://codesandbox.io/s/p9nrkjw7lj
@lookfirst give beta.7 a try? Let me know.
@jaredpalmer Wow, that is an interesting fix, but I was able to still duplicate the problem in the sandbox you mentioned above...

From the blog post you reference in the codebase:
"An optimal solution would be to find places where setState() might be called after a component has unmounted, and fix them."
I think the solution that does not require you to change the onSubmit() api, would be to make the internal validation promise cancellable so that it does not call setState().
in my app it seems to be doing a page reload like a normal html form would
do. It only happens to me when I use one of the onSubmit methods like
setSubmitting
On Thu, Jul 12, 2018 at 4:05 AM Jon Stevens notifications@github.com
wrote:
@jaredpalmer https://github.com/jaredpalmer Wow, that is an interesting
fix, but I was able to still duplicate the problem in the sandbox you
mentioned above...[image: image]
https://user-images.githubusercontent.com/85355/42629515-8af9679e-85a1-11e8-8b1e-e776aa9acb22.pngFrom the blog post you reference in the codebase:
"An optimal solution would be to find places where setState() might be
called after a component has unmounted, and fix them."I think the solution that does not require you to change the onSubmit()
api, would be to make the internal validation promise cancellable so that
it does not call setState().—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/jaredpalmer/formik/issues/597#issuecomment-404475768,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAxFzQY3Koqcal-Skbqwg5q96bl3lIB_ks5uFy18gaJpZM4Tfdit
.
I have a redux form and this happened when I wanted to set a key to my Field with files format,
when I set my key to new Date() this warning happened.
I set the key to random number but it did not work.
what should I do?
Most helpful comment
It's because the yup validations are done in a promise and when the promise resolves it calls setFormikState which calls
this.setState(s, callback);without checking if the component is still mounted: https://github.com/jaredpalmer/formik/blob/0b8346d302e71515b8cd987e528908003e0145f6/src/FastField.tsx#L225