【问题标题】:Search box with React-Query带有 React-Query 的搜索框
【发布时间】:2021-06-09 04:01:24
【问题描述】:

我正在尝试通过text 实现产品搜索。使用react-query 获取数据。以下实现正在运行,但对我来说感觉不对。让我知道我是否做得过火以及react-query 是否有更简单的解决方案。

import { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import { useQueryClient } from 'react-query';
import ProductCard from '@/components/cards/ProductCard';
import { useQueryProducts } from '@/hooks/query/product';
import { selectSearch } from '@/store/search';

// function fetchProductsByFilter(text){}

const Shop = ({ count }) => {
  const [products, setProducts] = useState([]);
  const [loading, setLoading] = useState(true);

  const { text } = useSelector(selectSearch);

  const productsQuery = useQueryProducts(count);

  useEffect(() => {
    setProducts(productsQuery.data);
    setLoading(false);
  }, []);

  const queryClient = useQueryClient();

  useEffect(() => {
    const delayed = setTimeout(() => {
      queryClient.prefetchQuery(['searchProductsByText'], async () => {
        if (text) {
          const data = await fetchProductsByFilter(text);
          setProducts(data);
          setLoading(false);
          return data;
        }
      });
    }, 300);
    return () => clearTimeout(delayed);
  }, [text]);

  return (
    <div className="container-fluid">
      <div className="row">
        <div className="col-md-3">search/filter menu</div>

        <div className="col-md-9">
          {loading ? (
            <h4 className="text-danger">Loading...</h4>
          ) : (
            <h4 className="text-danger">Products</h4>
          )}

          {products.length < 1 && <p>No products found</p>}

          <div className="row pb-5">
            {products.map((item) => (
              <div key={item._id} className="col-md-4 mt-3">
                <ProductCard product={item} />
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
};

// async function getServerSideProps(context) {}

export default Shop;

【问题讨论】:

    标签: javascript reactjs next.js react-query


    【解决方案1】:

    这对我来说似乎不是很地道。使用 react-query,使用过滤器的关键是将它们放入查询键中。由于每次更改键时 react-query 都会重新获取,因此每次更改过滤器时都会重新获取,这通常是您想要的。这是一种非常声明性的做事方式。根本不需要 useEffect。

    如果在从选择中选择某些内容或单击应用按钮时发生这种情况,那真的是您所需要的:

    const [filter, setFilter] = React.useState(undefined)
    const { data, isLoading } = useQuery(
      ['products', filter], 
      () => fetchProducts(filter)
      { enabled: Boolean(filter) }
    )
    

    在这里,只要过滤器为 undefined,我还将禁用查询 - 只要我们调用 setFilter,就会开始获取。


    如果涉及到输入文本字段,我建议进行一些去抖动以避免触发太多请求。 useDebounce hook 非常适合。您仍然拥有useState,但您将使用去抖动值进行查询:

    const [filter, setFilter] = React.useState(undefined)
    const debouncedFilter = useDebounce(filter, 500);
    const { data, isLoading } = useQuery(
      ['products', debouncedFilter], 
      () => fetchProducts(debouncedFilter)
      { enabled: Boolean(debouncedFilter) }
    )
    

    【讨论】:

    • 哇,太酷了。谢谢!!!向你学习很多。
    【解决方案2】:

    如果在从选择中选择某些内容或单击应用按钮时发生这种情况,那真的是您所需要的:

    const [filter, setFilter] = useState<string>('')
    const isEnabled = Boolean(filter)
    const { data, isLoading } = useQuery(
      ['products', filter], 
      () => fetchProducts(filter)
      { enabled:  enabled: filter ? isEnabled : !isEnabled, }
    )
    
     <input type="text" onChange={(e) => setFilter(e.target.value)}/>
    

    【讨论】:

      猜你喜欢
      • 2021-01-28
      • 1970-01-01
      • 1970-01-01
      • 2020-10-13
      • 2013-04-03
      • 2013-12-21
      • 1970-01-01
      • 1970-01-01
      • 2018-12-13
      相关资源
      最近更新 更多