reactQuery onChange 请求取消

时间:2021-02-14 12:19:06

标签: reactjs typescript fetch react-query

我无法在 useQuery 挂钩上设置请求取消。 我检查了文档并像这样尝试documentation 但是我没有像 cancel() 这样的方法可用于 res 承诺。 我将代码更改为 axios,因为我在 fetch 时遇到了一些解析器错误,我做了这样的事情: 这是我的代码:

useQuery(['city', value], async () => {
    let cancel:Canceler;
    const promise = 
    axios.get(`http://localhost:8000/citiesname=${value}&_limit=1`, {
        cancelToken: new axios.CancelToken(exec => cancel = exec),
    }) as Promise<AxiosPromise<any>> & Cancelable;
    promise.cancel= () => {
        cancel();
    }
    const res = await promise;
    setData(res.data);
},{
    enabled: value !== undefined
})

你能帮我解决这个问题吗?这真的很重要,因为我不想在用户每次输入内容时都发送请求,我只希望在他输入最后一个字符时发生

所以现在我不返回数据,我通过 setData setter 将它设置为我自己的状态,但它不起作用,仍然在每次更改时发送请求

2 个答案:

答案 0 :(得分:2)

与文档中的示例的不同之处在于您使用的是 async / await,而文档则没有。您不是返回添加取消函数的 Promise,而是返回一个新的 Promise,由 async 关键字创建。

在这种情况下,您需要坚持链接 .then

const { data } = useQuery(['city', value], () => {
    const controller = new AbortController();
    const signal = controller.signal;
    
    const promise = fetch(`http://localhost:8000/cities?name=${value}`,{
        signal
    });

    promise.cancel = () => controller.abort()
    
    return promise.then(res => res.json())
},{
    enabled: value !== undefined
})

答案 1 :(得分:2)

@TkDodo 的回答解决了 Javascript 问题,但还有一个额外的 Typescript 问题。 react-query 包希望您设置一个属性 .overrideProvider(getConnectionToken()).useValue(jest.fn()),它不是 cancel 的本机属性。因此,在某些时候,我们必须断言您的 Promise 变量是具有 promise 方法的类型。

在 react-query 包 they use cancel() 中将 as any 添加到承诺中,但我们可以做得更好!包 defines.cancel 对象的接口,但由于某种原因未导出。

Cancelable

您仍然可以使用 interface Cancelable { cancel(): void } /async 语法(至少从代码的角度来看,这是未经测试的所以我不知道在运行时是否有任何问题),但是您需要分配在您await解析之前,Promisefetch 返回到一个变量。

await