rxjs 异步调用_如何使用RxJS轻松取消useEffect HTTP调用

rxjs 异步调用

Now that React Hooks have been officially released, even more patterns are emerging across the Internet.

现在, React Hooks正式发布了,互联网上出现了更多的模式。

useEffect (useEffect)

The useEffect hook’s among the most popular, as it can replace componentDidMount, componentDidUpdate, and componentWillUnmount.

useEffect钩子是最受欢迎的钩子,因为它可以替换componentDidMountcomponentDidUpdatecomponentWillUnmount

Most of the initialization, updates, and cleanup logic a component may need can be put inside of useEffect.

组件可能需要的大多数初始化,更新和清除逻辑都可以放在useEffect

丑陋的用户体验 (An Ugly User Experience)

On a recent project, I encountered a scenario where useEffect acted on HTTP requests I was no longer interested in.

在最近的项目中,我遇到了一个场景,其中useEffect对我不再感兴趣的HTTP请求起作用。

Conceptually, the UI was like this:

从概念上讲,UI如下所示:

  • On first load, fetch the list of fruits and render a <button> for each one.

    第一次加载时,获取水果列表并为每个水果渲染一个<button>

  • Click a <button> to fetch that fruit’s details.

    单击<button>以获取该水果的详细信息。

But watch what happens when I click multiple fruits in a row

但是请注意当我连续单击多个水果时会发生什么

Way after I stopped clicking, the fruit detail section kept changing!

我停止点击后的方式,水果详细信息部分不断变化!

代码 (The Code)

Let’s see my custom hook that leverages useEffect.

让我们看看利用useEffect自定义钩子。

Here’s the Codesandbox and GitHub links if you wish to follow along. The file is useFruitDetail.js.

如果您想继续,这里是CodesandboxGitHub链接。 该文件是useFruitDetail.js

import { useEffect, useState } from 'react';
import { getFruit } from './api';

export const useFruitDetail = (fruitName) => {
  const [fruitDetail, setFruitDetail] = useState(null);

  useEffect(() => {
    if (!fruitName) {
      return;
    }

    getFruit(fruitName).then(setFruitDetail);
  }, [fruitName]);

  return fruitDetail;
};

Whenever fruitName changes, we’ll request its details. And we have no way of cancelling a request! So quickly re-running this results in many state changes that we’re no longer interested in.

每当fruitName更改时,我们都将请求其详细信息。 而且我们无法取消请求! 因此,快速重新运行此操作会导致许多状态更改,而我们不再对此感兴趣。

If you render this to the UI, you get a messy user experience where the detail section keeps flickering until the final request is resolved.

如果将其呈现到UI,您将获得混乱的用户体验,其中详细信息部分会一直闪烁,直到最终请求得到解决。

输入RxJS (Enter RxJS)

Ignoring old requests is trivial with RxJS.

使用RxJS可以忽略旧的请求。

It can do so much more than what I’ll demo here, so I highly recommend you dive into it!

它可以做的比我在此演示的要多得多,因此我强烈建议您深入学习

This portion of our code, the effect code, needs to change.

我们这部分代码( 效果代码)需要更改。

() => {
  if (!fruitName) {
    return;
  }

  getFruit(fruitName).then(setFruitDetail);
};

Instead of a Promise, let’s convert getFruit into an Observable using the RxJS defer function. And instead of .then, we’ll call .subscribe.

让我们使用RxJS defer函数将getFruit转换为Observable,而不是Promise。 而代替.then ,我们会打电话给.subscribe

import { defer } from 'rxjs';

// ...

() => {
  if (!fruitName) {
    return;
  }

  defer(() => getFruit(fruitName)).subscribe(setFruitDetail);
};

This doesn’t fix the issue yet. We still need to unsubscribe if fruitName changes.

这还不能解决问题。 如果fruitName更改,我们仍然需要退订

According to React’s docs, we can return a function that’ll be executed at the end of our effect. This acts as the cleanup logic.

根据React的文档 ,我们可以返回一个将在效果结束时执行的函数。 这充当清理逻辑。

So something like this:

所以像这样:

() => {
  if (!fruitName) {
    return;
  }

  const subscription = defer(() => getFruit(fruitName)).subscribe(
    setFruitDetail
  );

  return () => {
    subscription.unsubscribe();
  };
};

有用! (It Works!)

This experience is much cleaner!

这种经验要干净得多!

By clicking another fruit, useEffect sees fruitName change and runs the previous effect’s cleanup logic. As a result, we unsubscribe from the previous fetch call and focus on the current one.

通过单击另一个水果, useEffect将看到fruitName更改并运行前一个效果的清理逻辑。 结果,我们取消了上一个提取调用的订阅,并专注于当前调用。

Now our UI patiently waits until the user’s done clicking and the latest fruit’s details return.

现在,我们的用户界面耐心等待,直到用户单击完毕并返回最新水果的详细信息。

Thanks for following this tutorial to the end!

感谢您结束本教程的学习!

翻译自: https://www.freecodecamp.org/news/how-to-easily-cancel-useeffect-http-calls-with-rxjs-d1be418014e8/

rxjs 异步调用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值