在useEffect

时间:2020-07-08 06:39:24

标签: javascript reactjs react-hooks use-effect

我已经在useEffect钩子上订阅了消息服务的一些更新。仔细阅读react hooks文档和资源,我找不到我的代码对某些观察的答案。这是我的代码段:

import React, { useState, useEffect } from "react";
import { messageService } from "../_services";

function App() {
  const [count, setCount] = useState(0);
  useEffect(() => {
    const subscription = messageService.onMessage().subscribe(message => {
      setCount(count + 1);
    });
    return () => {
      console.log("unmount");
      subscription.unsubscribe();
    };
  }, [count]);

  function sendMessage() {
    messageService.sendMessage("message");
  }

  return (
    <div className="jumbotron">
      <button onClick={sendMessage} className="btn btn-primary mr-2">
        Send Message
      </button>
      {count}
    </div>
  );
}

export { App };

现在我无法理解两种行为:

  1. 由于useEffect钩子具有count作为依赖项,因此我应该遇到一个无限循环问题,但我发现是unmount被调用了。 React是否会因无限循环而卸载App组件?如果这样做,我在任何地方都找不到提到的内容
  2. 即使调用unmount,也会保留count的值。怎么可能

我知道一种解决方法,那就是我需要使用useRef来保留count并将其从钩子的依赖项中删除,并在有计数更新时将其与强制更新一起删除。

我正在寻找的是上述两个问题的答案,是否有更好的方法可以解决此问题 预先感谢。

Stackblitz link for working app in case you want to try out

1 个答案:

答案 0 :(得分:1)

清除效果不仅可以在组件卸载之前进行清理,还可以在组件多次渲染(通常按照 )进行also 时进行清理,先执行上一个效果,然后再执行下一个效果

另外,根据您的情况,count不应位于useEffect中,因为您可以使用functional updates

useEffect(() => {
  const subscription = messageService.onMessage().subscribe((message) => {
    setCount((p) => p + 1);
  });
  return () => {
    subscription.unsubscribe();
  };
}, []);

即使调用了unmount,仍保留了count的值。怎么可能?

那是由于closures