React Hook – 清理 useEffect

今天我们将看到如何使用useEffect React Hook的清理函数。
当你更新卸载组件的状态时,React会抛出这样的错误:
"无法在卸载的组件上执行React状态更新。这是一个无操作,但它表明您的应用程序中存在内存泄漏。要修复,请取消componentWillUnmount方法中的所有订阅和异步任务。”**

useEffect(() => {
    //Do all the job, for example, subscribe a websocket channel
    return function(){
        //Unsubscribe websocket channel
    };
}, []);

----1防止更新卸载组件:
在这里你将学习如何防止这个问题

  useEffect(() => {
    let isCancelled = false;
    const runAsync = async () => {
      try {
        if (!isCancelled) {
          // do the job
        }
      } catch (e) {
        if (!isCancelled) {
          throw e;
        }
      }
    };

    runAsync();

    return () => {
      isCancelled = true;
    };
  }, [...]);

Usage with setInterval/setTimeout:
This is a nice solution to abort setInterval/setTimeout:
2使用与setInterval / setTimeout:
这是中止setInterval/setTimeout的一个很好的解决方案:

useEffect(() => {
  const interval = setInterval(() => {
    console.log('Five Seconds!');
  }, 5000);
  return () => clearInterval(interval);
}, []);

----3使用Firestore实时数据库:
这在使用Firestore实时数据库时非常有用:

useEffect(() => {
    //Subscribe: firebase channel
    const cleanUp = firebase.firestore().collection('photos') .doc(id)
        .onSnapshot( doc => {
            setLoading(false);
            setPhotos(doc)
        }, err => { setError(err); }
    );
    return () => cleanUp(); //Unsubscribe
 }, []);

如果您忘记清理您的firestore订阅,您可能会收到不必要的请求。

4Usage with fetch + AbortController:
Cancel fecth with AbortController from fetch/es6:

使用fetch + AbortController:
用AbortController从fetch/es6取消fecth:

  useEffect(() => {
    const abortController = new AbortController();
    const fetchData = async () => {
      try {
        const ret = await fetch("/companies", { signal: abortController.signal });
        const data = await ret.json();
        // ...
      }
      catch(error) {
        if (abortController.signal.aborted) {
          // cancelled
        }
        else
          throw error;
      };
    };

    fetchData();

    return () => abortController.abort();
  }, [companies]);

–5Usage with axios request:
Here is how to cancel the request with axios.

useEffect(() => {
  const source = axios.CancelToken.source();

  const fetchData = async () => {
    try {
      const response = await Axios.get("/companies", {
        cancelToken: source.token
      });
      // ...
    } catch (error) {
      if (Axios.isCancel(error)) {
        //cancelled
      } else {
        throw error;
      }
    }
  };

  fetchData()

  return () => {
    source.cancel();
  };
}, [companies]);

useEffect函数等价于React类组件中的componentDidMount。
这个清理函数相当于React类组件中的componentWillUnmount函数。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值