reactstrap 模式中的 Graphql 突变 - 无法对未安装的组件执行 React 状态更新

Graphql mutation in reactstrap modal - Can't perform a React state update on an unmounted component

注意:我已经看到很多关于此警告消息的问题,但大多数问题似乎都是关于在安装组件后立即异步获取数据,而我正在尝试执行 graphql 突变发送在通过单击触发的表单提交上,所以我认为我不能采用类似的方法。

另外,我正在使用钩子,所以一个相关的解决方案to/using会很好。

我在 reactstrap 模式中有一个表单,在提交时,进行 graphql 修改。如何确保组件在卸载后不会尝试更新状态,以免出现此错误?

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.

仅当用户在提交后立即离开页面时才会出现警告。大多数时候用户永远不会这样做,而是会提交然后在页面上停留至少几秒钟,在这种情况下永远不会出现警告并且没有问题,但我不想采取任何机会。

这是表单标签的 onSubmit 中的 handleSubmit 代码:

const handleSubmit = async e => {
  e.preventDefault();
  const contactToUpdate = {
    id,
    name: e.target.name.value,
    email: e.target.email.value,
  };
  const addressToUpdate = {
    city: e.target.city.value,
    state: e.target.state.value,
    street1: e.target.street1.value,
    street2: e.target.street2.value,
    zip: e.target.zip.value
  };
  const updateContact = updateCoordinators(
    contactToUpdate,
    addressToUpdate
  );
  try {
    const apiData = await API.graphql(graphqlOperation(updateContact));
    if (apiData) {
      const newContactInfo = apiData.data.updatePerson;
      setContactInfo(newContactInfo);
    }
    setToastType("success");
    setShowSnackbar(true);
    closeModal();
  } catch (err) {
    console.error(err);
    setToastType("error");
    setShowSnackbar(true);
  }
};

问题不在于突变,而在于小吃店!它被设置为在 setTimeout 中停留 3 秒,我没有意识到,因为我没有编写该代码。如果用户在这 3 秒结束之前点击离开,它会尝试将其状态设置为 false,即使它现在已被卸载,也会导致警告。在 snackbar 组件中,我将 setTimeout 放入 useEffect 并在 return 的回调中清除它,这样如果卸载 snackbar 组件,它将清除超时,因此在卸载后永远不会尝试设置状态,就像这样:

  useEffect(() => {
    const timeout = setTimeout(() => {
      setShowSnackbar(false);
    }, 3000);
    return () => clearTimeout(timeout);
  });