无法在表单提交时使用 Formik 执行 React 状态更新
Can't perform a React state update with Formik on form submit
当我单击按钮提交表单时收到以下警告:
Warning: Can't perform a React state update 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 a useEffect cleanup function.
Formik@http://localhost:3000/static/js/vendors~main.chunk.js:3815:28
div
div
CheckIn@http://localhost:3000/static/js/main.chunk.js:382:17
Route@http://localhost:3000/static/js/vendors~main.chunk.js:43553:29
表单有效时出现警告。第二次单击按钮后,它成功提交。
import React from "react";
import { Formik } from "formik";
import { useHistory } from "react-router-dom";
export default function CheckIn({ user, setUser }) {
const history = useHistory();
return (
<div>
<Formik
initialValues={{
name: "",
mail: ""
}}
validate={(values) => {
const errors = {};
if (!values.mail && user.mail) {
values.mail = user.mail;
}
if (!values.name && user.name) {
values.name = user.name;
}
if (!values.mail) {
errors.mail = "Required";
} else if (
!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.mail)
) {
errors.mail = "Invalid mail address";
}
return errors;
}}
onSubmit={(values, { setSubmitting }) => {
history.push("/success");
setUser(values);
setSubmitting(false);
}}
>
{({
values,
errors,
handleChange,
handleBlur,
handleSubmit,
isSubmitting,
}) => (
<form onSubmit={handleSubmit}>
<input
type="name"
name="name"
placeholder="Name"
style={errors.name ? { border: "2px solid red" } : {}}
onChange={handleChange}
onBlur={handleBlur}
value={values.name || user.name}
/>
<input
type="email"
name="mail"
placeholder="E-Mail"
style={errors.mail ? { border: "2px solid red" } : {}}
onChange={handleChange}
onBlur={handleBlur}
value={values.mail || user.mail}
/>
<button
type="submit"
disabled={isSubmitting}
className="btn wide"
>
Checkin
</button>
</form>
)}
</Formik>
</div>
);
}
不幸的是,这个警告对我没有帮助,一方面我不明白,另一方面,也没有 useEffect。
问题:history.push
此错误是由您的表单的 onSubmit
处理程序引起的:
onSubmit={(values, { setSubmitting }) => {
history.push("/success");
setUser(values);
setSubmitting(false);
}}
您要做的第一件事是调用 history.push
,它会离开页面并导致 Formik
组件卸载。然后你调用 setSubmitting
尝试更新 Formik
组件的状态 - 但它已经卸载所以你得到错误 "Can't perform a React state update on an unmounted组件。"
只是将 history.push
移动到列表中的最后一个操作导致错误消失,但我不喜欢这个解决方案,因为 React setState
调用是异步的所以在技术上仍然有可能发生错误。我不明白为什么您在离开此页面时需要手动调用 setSubmitting
,因此我的建议是完全删除该调用。
onSubmit={(values) => {
setUser(values);
history.push("/success");
}}
确保 setUser
没有更新将被导航卸载的组件的状态。
当我单击按钮提交表单时收到以下警告:
Warning: Can't perform a React state update 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 a useEffect cleanup function.
Formik@http://localhost:3000/static/js/vendors~main.chunk.js:3815:28
div
div
CheckIn@http://localhost:3000/static/js/main.chunk.js:382:17
Route@http://localhost:3000/static/js/vendors~main.chunk.js:43553:29
表单有效时出现警告。第二次单击按钮后,它成功提交。
import React from "react";
import { Formik } from "formik";
import { useHistory } from "react-router-dom";
export default function CheckIn({ user, setUser }) {
const history = useHistory();
return (
<div>
<Formik
initialValues={{
name: "",
mail: ""
}}
validate={(values) => {
const errors = {};
if (!values.mail && user.mail) {
values.mail = user.mail;
}
if (!values.name && user.name) {
values.name = user.name;
}
if (!values.mail) {
errors.mail = "Required";
} else if (
!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.mail)
) {
errors.mail = "Invalid mail address";
}
return errors;
}}
onSubmit={(values, { setSubmitting }) => {
history.push("/success");
setUser(values);
setSubmitting(false);
}}
>
{({
values,
errors,
handleChange,
handleBlur,
handleSubmit,
isSubmitting,
}) => (
<form onSubmit={handleSubmit}>
<input
type="name"
name="name"
placeholder="Name"
style={errors.name ? { border: "2px solid red" } : {}}
onChange={handleChange}
onBlur={handleBlur}
value={values.name || user.name}
/>
<input
type="email"
name="mail"
placeholder="E-Mail"
style={errors.mail ? { border: "2px solid red" } : {}}
onChange={handleChange}
onBlur={handleBlur}
value={values.mail || user.mail}
/>
<button
type="submit"
disabled={isSubmitting}
className="btn wide"
>
Checkin
</button>
</form>
)}
</Formik>
</div>
);
}
不幸的是,这个警告对我没有帮助,一方面我不明白,另一方面,也没有 useEffect。
问题:history.push
此错误是由您的表单的 onSubmit
处理程序引起的:
onSubmit={(values, { setSubmitting }) => {
history.push("/success");
setUser(values);
setSubmitting(false);
}}
您要做的第一件事是调用 history.push
,它会离开页面并导致 Formik
组件卸载。然后你调用 setSubmitting
尝试更新 Formik
组件的状态 - 但它已经卸载所以你得到错误 "Can't perform a React state update on an unmounted组件。"
只是将 history.push
移动到列表中的最后一个操作导致错误消失,但我不喜欢这个解决方案,因为 React setState
调用是异步的所以在技术上仍然有可能发生错误。我不明白为什么您在离开此页面时需要手动调用 setSubmitting
,因此我的建议是完全删除该调用。
onSubmit={(values) => {
setUser(values);
history.push("/success");
}}
确保 setUser
没有更新将被导航卸载的组件的状态。