为什么这些功能工作不同?

仅在未卸载组件的情况下,我试图在设置API调用后设置属性的状态。在第一个函数中,变量“ unmount”在函数“ Component”中初始化。在这种情况下,我会收到以下警告:“无法在已卸载的组件上执行React状态更新。这是空操作,但表明您的应用程序中存在内存泄漏。”


在第二个函数中,我全局初始化变量“ unmount”,在这种情况下,我没有收到任何警告。


显示警告:

function Component() {

  const [emailSent, setEmailSent] = useState(false);


  var unmounted = false;

  async function handleClickEvent() {

  try {

   await AuthApi.sendRecoverAccountEmail('123');

   !unmounted && setEmailSent(true);

  } catch (err) {

    !unmounted && setIsSendingEmail(false);

  }

 }


 useEffect(() => {

   return () => {

    unmounted = true;

   };

 }, []);

}

没有警告:

var unmounted = false;

function Component() {

const [emailSent, setEmailSent] = useState(false);


async function handleSendEmail(formValues) {

 try {

  await AuthApi.sendRecoverAccountEmail('123');

  !unmounted && setEmailSent(true);

 } catch (err) {

  !unmounted && setIsSendingEmail(false);

 }

}


useEffect(() => {

  return () => {

   unmounted = true;

  };

 }, []);

}

任何人都可以解释为什么会这样吗?


慕标琳琳
浏览 184回答 2
2回答

守着一只汪

在第一个示例中,unmounted总是false在每次渲染之后。这是不使用全局实例的正确方法:function Component() {  const [emailSent, setEmailSent] = useState(false);  const unmounted = useRef(false);  async function handleSendEmail(formValues) {    try {      await AuthApi.sendRecoverAccountEmail('123');      !unmounted.current && setEmailSent(true);    } catch (err) {      !unmounted.current && setIsSendingEmail(false);    }  }  useEffect(() => {    return () => {      unmounted.current = true;    };  }, []);}

Qyouu

一个有趣的问题。您可能会发现有关钩子的常见问题解答很有用,因为我认为它相当具体地解决了您的问题。在第一个示例中,卸载的var是组件属性的一部分,而在第二个示例中,它只是作为javascript闭包的一部分而获得的。通常,您要确保将更改的挂载参数作为componentDidUnmount生命周期方法的一部分。我认为,如果您将unmount添加到依赖项列表中,可能会起作用吗?我通常在Clojurescript中使用另一个框架的react,所以我并不完全熟悉主要javascript接口的语义,但这至少是为什么您会收到第一个示例警告的原因。在第一个示例中,如果将最后一部分更改为以下内容,会发生什么?useEffect(() => {  return () => {   unmounted = true;  }; }, [unmounted]);}您可能需要将unmount定义为更正式的react属性,而不仅仅是组件中包含的属性。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript