有人能帮助我使用creatApi和redux工具包中的查询实现来实现去抖动功能吗?先谢了。
mitkmikd1#
我个人并没有发现RTK Query中有任何开箱即用的反跳实现。但是你可以自己实现它。定义一个API,我用的是开放库的api:
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; type BooksSearchResult = { docs: Book[]; }; type Book = { key: string; title: string; author_name: string; first_publish_year: number; }; export const booksApi = createApi({ reducerPath: 'booksApi', baseQuery: fetchBaseQuery({ baseUrl: 'http://openlibrary.org/' }), endpoints: builder => ({ searchBooks: builder.query<BooksSearchResult, string>({ query: term => `search.json?q=${encodeURIComponent(term)}`, }), }), }); export const { useSearchBooksQuery } = booksApi;
接下来你需要的是去抖动钩子,它保证一些值只在指定的延迟后改变:
function useDebounce(value: string, delay: number): string { const [debouncedValue, setDebouncedValue] = useState(value); useEffect(() => { const handler = setTimeout(() => { setDebouncedValue(value); }, delay); return () => { clearTimeout(handler); }; }, [value, delay]); return debouncedValue; }
在搜索表单上使用防反跳挂钩:
import React, { useEffect, useState } from "react"; import BookSearchResults from "./BookSearchResults"; function useDebounce(value: string, delay: number): string { const [debouncedValue, setDebouncedValue] = useState(value); useEffect(() => { const handler = setTimeout(() => { setDebouncedValue(value); }, delay); return () => { clearTimeout(handler); }; }, [value, delay]); return debouncedValue; } const DebounceExample: React.FC = () => { const [searchTerm, setSearchTerm] = useState(""); const debouncedSearchTerm = useDebounce(searchTerm, 500); return ( <React.Fragment> <h1>Debounce example</h1> <p>Start typing some book name. Search starts at length 5</p> <input className="search-input" type="text" placeholder="Search books" value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} /> <BookSearchResults searchTerm={debouncedSearchTerm}></BookSearchResults> </React.Fragment> ); }; export default DebounceExample;
型在搜索结果组件中使用搜索查询钩子。它使用自己的状态来表示搜索项值,如果你想为去抖动值添加额外的“过滤器”,这是非常方便的(例如,只有当搜索项的长度大于某个值时才开始查询)。
import React, { useState, useEffect } from "react"; import { useSearchBooksQuery } from "./booksApi"; type BookSearchResultsProps = { searchTerm: string; }; const BookSearchResults: React.FC<BookSearchResultsProps> = ({ searchTerm }: BookSearchResultsProps) => { const [filteredSearchTerm, setFilteredSearchTerm] = useState(searchTerm); const { data, error, isLoading, isFetching } = useSearchBooksQuery( filteredSearchTerm ); const books = data?.docs ?? []; useEffect(() => { if (searchTerm.length === 0 || searchTerm.length > 4) { setFilteredSearchTerm(searchTerm); } }, [searchTerm]); if (error) { return <div className="text-hint">Error while fetching books</div>; } if (isLoading) { return <div className="text-hint">Loading books...</div>; } if (isFetching) { return <div className="text-hint">Fetching books...</div>; } if (books.length === 0) { return <div className="text-hint">No books found</div>; } return ( <ul> {books.map(({ key, title, author_name, first_publish_year }) => ( <li key={key}> {author_name}: {title}, {first_publish_year} </li> ))} </ul> ); }; export default BookSearchResults;
完整示例可在here上找到。
zte4gxcn2#
在我的情况下,下面的解决方案效果很好。我使用了分量去抖的方法。使用任何去抖fn,以我的方式:
npm i debounce
然后在组件中
import debounce from 'debounce'; const Component = () => { const { data, refetch } = useYourQuery(); const [mutate] = useYourMutation(); const handleDebouncedRequest = debouce(async () => { try { // you can use refetch or laze query way await refetch(); await mutate(); } catch {} }, 2000); // ...other component logic }
nnvyjq4y3#
在第一次呈现之后,我们的request钩子将尝试发送请求,我们可以使用skipToken绕过它,直到searchTerm返回某个值,才发送请求
import { useDebounce } from 'use-debounce' import { skipToken } from '@reduxjs/toolkit/query' const [storeName, setStoreName] = useState('') const [searchTerm] = useDebounce(storeName, 1500) const { data } = useSearchStoresRequestQuery(searchTerm || skipToken)
有关skipToken的详细信息:https://redux-toolkit.js.org/rtk-query/usage/conditional-fetching也在我的useSearchStoresRequestQuery中
endpoints: (builder) => ({ getStoresWithSearchRequest: builder.query({ query: ({searchTerm}) => { return { url: `admin/v1/stores?searchTerm?${searchTerm}`, method: 'GET', } },
3条答案
按热度按时间mitkmikd1#
我个人并没有发现RTK Query中有任何开箱即用的反跳实现。但是你可以自己实现它。
定义一个API,我用的是开放库的api:
接下来你需要的是去抖动钩子,它保证一些值只在指定的延迟后改变:
在搜索表单上使用防反跳挂钩:
型
在搜索结果组件中使用搜索查询钩子。它使用自己的状态来表示搜索项值,如果你想为去抖动值添加额外的“过滤器”,这是非常方便的(例如,只有当搜索项的长度大于某个值时才开始查询)。
完整示例可在here上找到。
zte4gxcn2#
在我的情况下,下面的解决方案效果很好。
我使用了分量去抖的方法。使用任何去抖fn,以我的方式:
然后在组件中
nnvyjq4y3#
在第一次呈现之后,我们的request钩子将尝试发送请求,我们可以使用skipToken绕过它,直到searchTerm返回某个值,才发送请求
有关skipToken的详细信息:https://redux-toolkit.js.org/rtk-query/usage/conditional-fetching
也在我的useSearchStoresRequestQuery中