表格过滤及其数据请求

100 阅读1分钟

需求: 输入手机号,再从订单中筛选出这个手机号下单订单

image.png

一开始后端没有给接口的时候 我想既然能拿到数据 就在所有数据里面通过数组的方法过滤出来就好了,

const sortedOrdered = allData
        .filter((row) => {
          const values = Object.values(row);
          console.log("has", values.includes(searchValue.trim()));
          //  /row.phone == searchValue.trim()
          if (values.includes(searchValue.trim())) {
            console.log("row", row);
            return row;
          }
        })
        .map((item: tableItem) => {
          const {
            create_at,
            order_id,
            payment,
            reference,
            confirmed_order,
            phone,
          } = item;
          return createTransactionTableData({
          //因为我用的是mui的表格 所以有这个返回订单对象的函数
            create_at,
            order_id,
            payment,
            reference,
            confirmed_order,
            phone,
          });
        });

然后再利用useSWRInfinit去一个个发请求 拿到所有的数据,因为后端返回的数据默认是page=1,pageSize=10,

const getKey = (page, previousPageData) => {
    if (previousPageData && !previousPageData.length) return null; // 已经到最后一页
    return `/gdst-swap-api/orderhistory?page=${page + 1}`; // SWR key
  };
  const {
    data: pageOneData,
    size,
    setSize
  } = useSWRInfinite(getKey, fetcher, { parallel: true });

    useEffect(() => {
      if(pageOneData){
        if (size < pageOneData[0].data.total/pageOneData[0].data.page_size) {
          setSize(size + 1);//只要还有数据 就再发请求
        }
      }

    }, [pageOneData]);
    let allData = [];
 
    pageOneData?.forEach((item) => {
      allData.push(...item.data.items)
    });

这样子的话 数据量大的时候就会不断地发请求 直到拿到所有数据 而且如果用户在这个时候search 就会基于不完整的数据去过滤,就有问题。问了gpt老师,说是后端来处理会比较好 而后端也给到我接口了 就重新实现了 通过useState存储用户search的值 然后useSWR会在参数改变的时候发请求,以手机号为例

  const handleChange = (event) => {
    const { value } = event.target;
    setSearchValue(String(value));//这里之所以要分2个变量是因为我有一个button 需要拿到input里面的值
  } ;
  const handleSearchPhone = () => {
    if (searchValue) {
      setPhone(searchValue);
    } else {
      setPhone("");
    }
  };
     <StyledInputBase
          onChange={handleChange}
          placeholder="Search…"
          inputProps={{ "aria-label": "search" }}
        />
        <Button onClick={handleSearchPhone}>search</Button>
      </Search>

请求使用的是useSWR

  const fetcher = (url: string) => axios.get(url).then((res) => res.data);
  const { data, isLoading } = useSWR(
    `/history?page=${page + 1}&phone=${phone}`,
    fetcher
  );

然后展示的时候会根据data展示,是响应式的,归功于useSWR这个库(吹爆)