Reactjs react中的内存泄漏

Reactjs react中的内存泄漏,reactjs,react-hooks,formik,Reactjs,React Hooks,Formik,当我提交表格时,我得到了以下警告。提交后卸载的组件。如何解决这个问题 警告:无法对已卸载的组件执行React状态更新。这是一个no-op,但它表示应用程序中存在内存泄漏。要修复此问题,请取消useEffect清理函数中的所有订阅和异步任务 在Formik中(位于ItemCodeSpecForm.js:82) 在模态中(位于ItemCodeSpecForm.js:80) 在ErrorBoundary中(位于ItemCodeSpecForm.js:77) 悬而未决(见ItemCodeSpecForm

当我提交表格时,我得到了以下警告。提交后卸载的组件。如何解决这个问题

警告:无法对已卸载的组件执行React状态更新。这是一个no-op,但它表示应用程序中存在内存泄漏。要修复此问题,请取消useEffect清理函数中的所有订阅和异步任务

在Formik中(位于ItemCodeSpecForm.js:82) 在模态中(位于ItemCodeSpecForm.js:80) 在ErrorBoundary中(位于ItemCodeSpecForm.js:77) 悬而未决(见ItemCodeSpecForm.js:76) 在div中(位于ItemCodeSpecForm.js:74) 在ItemCodeSpecForm中(位于EditItemCodeSpec.js:61) 在div中(位于EditItemCodeSpec.js:60)

以下是表格

function ItemCodeSpecForm({ formType, mutation, removeSelect, initialData }) {
  const { number } = useParams();
  const itemCode = parseInt(number);
  const [open, setOpen] = useState(false);

  const client = useApolloClient();

  const gradeOptions = [
    { value: "HUMAN", label: "HUMAN" },
    { value: "DEFAULT", label: "DEFAULT" }
  ];

  const specClassOptions = [
    { value: "DS", label: "DS" },
    { value: "STAB", label: "STAB" }
  ];

  const defaultAdditional = {
    cursor: null
  };
  const shouldLoadMore = (scrollHeight, clientHeight, scrollTop) => {
    const bottomBorder = (scrollHeight - clientHeight) / 2;
    return bottomBorder < scrollTop;
  };
  const loadOptions = async (q = 0, prevOptions, { cursor }) => {
    console.log("qu", q * 1);
    const options = [];
    console.log("load");
    const response = await client.query({
      query: GET_PRODUCTS,
      variables: {
        filter: {
          number_gte: q * 1
        },
        skip: 0,
        first: 5,
        after: cursor
      }
    });

    console.log("res", response);
    response.data.products.products.map(item => {
      options.push({
        value: item.number,
        label: `${item.number} ${item.description}`
      });
    });

    return {
      options,
      hasMore: response.data.products.hasMore,
      additional: {
        cursor: response.data.products.cursor.toString()
      }
    };
  };

  const handleShow = () => {
    setOpen(true);
  };

  const handleHide = () => {
    setOpen(false);
  };

  return (
    <div className="modal">
      <button onClick={handleShow}>{formType}</button>
      <Suspense fallback={<div>Loading...</div>}>
        <ErrorBoundary>
          {open ? (
            <Modal>
              <button onClick={handleHide}>&#10006;</button>
              <Formik
                initialValues={{
                  product: !!initialData
                    ? { value: initialData.product, label: initialData.product }
                    : "",
                  spec_class: !!initialData
                    ? {
                        value: initialData.spec_class,
                        label: initialData.spec_class
                      }
                    : "",
                  grade: !!initialData
                    ? { value: initialData.grade, label: initialData.grade }
                    : ""
                }}
                validationSchema={Yup.object().shape({
                  product: Yup.string().required("Required"),
                  spec_class: Yup.string().required("Required"),
                  grade: Yup.string().required("Required")
                })}
                onSubmit={(data, { setSubmitting, resetForm }) => {
                  setSubmitting(true);
                  const { product, spec_class, grade } = data;
                  console.log({
                    variables: {
                      input: {
                        itemCode,
                        product: product.value,
                        spec_class: spec_class.value,
                        grade: grade.value
                      }
                    }
                  });
                  formType === "Add" ? console.log("a") : console.log("e");
                  formType === "Add"
                    ? mutation({
                        variables: {
                          input: {
                            itemCode,
                            product: product.value,
                            spec_class: spec_class.value,
                            grade: grade.value
                          }
                        }
                      })
                    : mutation({
                        variables: {
                          id: initialData.id,
                          input: {
                            product: product.value,
                            spec_class: spec_class.value,
                            grade: grade.value
                          }
                        }
                      });
                  setSubmitting(false);
                  resetForm();
                }}
              >
                {({
                  values,
                  isSubmitting,
                  handleChange,
                  setFieldValue,
                  touched,
                  errors
                }) => (
                  <Form>
                    <label htmlFor="product">Product</label>
                    <AsyncPaginate
                      name="product"
                      defaultOptions
                      debounceTimeout={300}
                      cacheOptions
                      additional={defaultAdditional}
                      value={values.product && values.product}
                      loadOptions={loadOptions}
                      onChange={option => setFieldValue("product", option)}
                      shouldLoadMore={shouldLoadMore}
                    />
                    {touched.product && touched.product ? (
                      <div>{errors.product}</div>
                    ) : null}
                    <label htmlFor="grade">Grade</label>
                    <Select
                      name="grade"
                      defaultValue={values.grade}
                      value={
                        gradeOptions
                          ? gradeOptions.find(
                              option => option.value === values.grade
                            )
                          : ""
                      }
                      options={gradeOptions}
                      onChange={option => setFieldValue("grade", option)}
                    />
                    {errors.grade && touched.grade ? <div>Required</div> : ""}
                    <label>Spec Class</label>
                    <Select
                      name="spec_class"
                      defaultValue={values.spec_class}
                      value={
                        specClassOptions
                          ? specClassOptions.find(
                              option => option.value === values.spec_class
                            )
                          : ""
                      }
                      options={specClassOptions}
                      onChange={option => setFieldValue("spec_class", option)}
                    />
                    {touched.spec_class && errors.spec_class ? (
                      <div>Required</div>
                    ) : (
                      ""
                    )}
                    <div>
                      <button disabled={isSubmitting} type="submit">
                        Submit
                      </button>
                    </div>
                    <pre>{JSON.stringify(values, null, 2)}</pre>
                  </Form>
                )}
              </Formik>
            </Modal>
          ) : null}
        </ErrorBoundary>
      </Suspense>
    </div>
  );
}
function ItemCodeSpecForm({formType,mutation,removeSelect,initialData}){
常量{number}=useParams();
const itemCode=parseInt(数字);
const[open,setOpen]=useState(false);
const client=useAppolloClient();
const grade选项=[
{价值:“人”,标签:“人”},
{值:“默认”,标签:“默认”}
];
常量specClassOptions=[
{值:“DS”,标签:“DS”},
{值:“STAB”,标签:“STAB”}
];
常量默认值附加={
游标:空
};
const shouldLoadMore=(scrollHeight、clientHeight、scrollTop)=>{
常量bottomBorder=(滚动高度-clientHeight)/2;
返回底部边界<滚动顶部;
};
const loadOptions=async(q=0,prevOptions,{cursor})=>{
控制台日志(“qu”,q*1);
常量选项=[];
控制台日志(“加载”);
const response=wait client.query({
查询:获取产品,
变量:{
过滤器:{
编号:q*1
},
跳过:0,
第一:5,,
之后:游标
}
});
console.log(“res”,响应);
response.data.products.products.map(项=>{
选项。推({
值:item.number,
标签:`${item.number}${item.description}`
});
});
返回{
选项,
hasMore:response.data.products.hasMore,
其他:{
游标:response.data.products.cursor.toString()
}
};
};
常量handleShow=()=>{
setOpen(真);
};
常量handleHide=()=>{
setOpen(假);
};
返回(
{formType}
{开门(
✖
{
设置提交(真);
const{product,spec_class,grade}=数据;
console.log({
变量:{
输入:{
项目代码,
产品:产品价值,
等级:等级值,
等级:等级。价值
}
}
});
formType==“添加”?控制台.log(“a”):控制台.log(“e”);
formType==“添加”
?突变({
变量:{
输入:{
项目代码,
产品:产品价值,
等级:等级值,
等级:等级。价值
}
}
})
:突变({
变量:{
id:initialData.id,
输入:{
产品:产品价值,
等级:等级值,
等级:等级。价值
}
}
});
设置提交(假);
resetForm();
}}
>
{({
价值观
提交,
handleChange,
setFieldValue,
感动的,
错误
}) => (
产品
setFieldValue(“产品”,选项)}
shouldLoadMore={shouldLoadMore}
/>
{touch.product&&touch.product(
{errors.product}
):null}
等级
option.value==values.grade
)
: ""
}
选项={gradeOptions}
onChange={option=>setFieldValue(“grade”,option)}
/>
{errors.grade&&toucted.grade?必需:“”
等级规范
option.value==values.spec\u类
)
: ""
}
选项={specClassOptions}
onChange={option=>setFieldValue(“spec_类”,option)}
/>
{moucted.spec_class&&errors.spec_class(
要求的
) : (
""
)}
提交
{JSON.stringify(值,null,2)}
)}
):null}
);
}

您有一段代码,需要在卸载组件时进行清理。。像eventListener一样

如果您提供一个@aiyan,我们可以在这里为您提供最好的帮助。当我提交表单时,模态正在卸载。因此,我需要检测提交何时完成
  useEffect(() => {

       return () => {
         //for cleanup
       };
  });