React js 搜索不适用于 graphql 分页

React js search doesn’t work on graphql pagination

我使用 react js 创建了一个搜索函数来过滤从 graphql 端点获取的 table 数据 代码:

const SearchRes = () => {
    let filtredRes = data.Orders.edges
        .filter(item => item.node.shippingAddress.name === (query));

    let res = filtredRes.length === 0 ? data.Orders.edges : filtredRes;                                         
    return res;
}

然后只需执行以下操作即可获取数据:

SearchRes.map(...)

这很好用,我可以进行搜索,但是当我实施 graphql 分页 时,搜索停止处理结果,它只在单击按钮以获得更多结果之前有效

代码:

import React, { useState, useEffect } from 'react'
import { gql, useQuery } from '@apollo/client';
import Table  from 'react-bootstrap/Table'
import Moment from 'react-moment';
import moment from "moment";
import { Link } from 'react-router-dom';
import Row from 'react-bootstrap/Row'
import Col from 'react-bootstrap/Col'
import { DangerousChangeType } from 'graphql';
import Search from './Search'
import Button from 'react-bootstrap/Button'

const GET_All_Orders = gql`
query Orders($input1: PaginationInput) {
    Orders(input: $input1){
     pageInfo {
       hasNextPage
       hasPreviousPage
     }
     edges{
       cursor
       node {
          id
          closed
          email
          createdAt
          updatedAt
          cancelledAt
          displayFinancialStatus
          displayFulfillmentStatus
          lineItems{
            edges{
              node {
                customAttributes{
                  key
                  value
                }
                id
                quantity
                title
                variant{
                  id
                  image {
                    altText
                    id
                    src
                  }
                  title
                  weight
                  weightUnit
                  price
                }
              }
            }
          }
          shippingAddress { 
            name
          }
         phone
         subtotalPrice
         totalPrice
         totalRefunded
         totalTax
         processedAt
       }
     }
   }
 }
`;


export default function AllOrders({ input1 }) {
    const { loading, error, data  , fetchMore} = useQuery(
        GET_All_Orders,
        {
            variables: {
                "input1": {
                    "num": 20,
                }
            },
        }
    );
    let date = new Date();
    const [query, setQuery] = useState('');

    if (loading) return <h4>読み込み中...</h4>;
    if (error) return `Error! ${error}`;
    
    const SearchRes = () => {
        let filtredRes = data.Orders.edges
            .filter(
                item => (
                    item.node.shippingAddress.name === (query) ||
                    item.node.email === (query)
                )
            );                                     
        let res = filtredRes.length === 0 ? data.Orders.edges : filtredRes;                                      
        return res;
    }

    return (
        <div>
           <Row > 
    <Col xs={10}> <h5>すべての注文</h5></Col>
    <Col><h5>  日付 : <Moment format="YYYY/MM/DD">
     
 { date}
            </Moment> </h5></Col>
  </Row>
   
 <br/>
 <Search getQuery={(q) => setQuery(q)} />
 <br/>
 <Table responsive hover size="sm">
  <thead>
    <tr>
    
    <th className="allOrders">注文日</th>
    <th className="allOrders">名前</th>
    <th className="allOrders">注文者メールアドレス</th>
    <th className="allOrders" >配送状態</th>
    <th className="allOrders" >支払状況</th>
      <th className="allOrders" >合計金額</th>
      <th className="allOrders" >詳細</th>
 
    </tr>
  </thead>
  <tbody>
 {SearchRes().map(({ edges ,node :{id , createdAt , displayFulfillmentStatus , displayFinancialStatus , totalPrice , email , shippingAddress: { 
            name
          } }}) => (
    
    
    <tr key={id}>
      
  
      <td>    <Moment format="YYYY/MM/DD">
       {createdAt}
            </Moment></td>
            <td>{ name} </td>  
      <td>{ email} </td>

      {displayFulfillmentStatus == "FULFILLED" ? <td className="success">配送済み</td> :  <td className="failed">未配送</td>}
    
 
 
 
       
      {displayFinancialStatus == "PAID" ? <td>支払済み</td> : <td>未払い</td> }
      <td>{totalPrice} </td>
      <td>  
      <Link to={`/orders/${id}`} className="btn btn-light">
      詳細
          </Link></td>
   
    </tr>
    
    

  ))}
  </tbody>
</Table>
    
            {/* button responsible for the pagination */}
            <div className="text-center">
                <Button
                    variant="light"
                    onClick={() => {
                        fetchMore({
                            variables: {
                                "input1": {
                                    "num": 20,
                                    "cursor": data.Orders.edges[data.Orders.edges.length - 1].cursor
                                }
                            },
                            updateQuery: (prevResult, { fetchMoreResult }) => {
                                fetchMoreResult.Orders.edges = [
                                    ...prevResult.Orders.edges,
                                    ...fetchMoreResult.Orders.edges
                                ];
                                return fetchMoreResult;
                            }
                        });
                    }}
                >
                    もっと
                </Button>
            </div>
        </div>
    );
}

可能问题是:

1 ) 我认为问题是因为按钮获取了一个不同的 table 也许这就是函数不搜索它的原因。

  1. 可能是因为 num 变量 因为它就像 graphql 中的第一个参数,所以当我写 时,你应该指定你应该得到多少结果” num": 20 在按钮中它总是 return 前 20 个结果而不是光标后的结果

我认为SearchRes函数应该是

const SearchRes = () => {
    let filtredRes = data.Orders.edges
        .filter(item => item.node.shippingAddress.name === (query) ||
                    item.node.email === (query));

    let res = query ? filtredRes : data.Orders.edges;                                         
    return res;
}

当查询为空时,这意味着用户让搜索输入为空,应该显示所有结果,当用户在搜索输入中输入内容时,应该只显示过滤后的结果,即使什么都没有匹配。 我不知道这是否是您的错误的真正原因,但我认为这确实是一个错误。

我会说您显然在查询中缺少偏移量。在您的 fetchMore 查询中,您仍然将 num: 20 作为变量传递,用您自己的话说

maybe because of the num variable because it is like the first parameter in graphql , you should specify how many result you should get so when i write "num": 20 in the button it will always return the first 20 result not the results after the cursor

是的,所以无论您获取的频率如何,您总是会获得前 20 个结果。我不知道你的后端实现,但基本上 offset 是结果应该开始返回的参数,所以如果你传递 offset: 10, num: 5,你应该得到项目 11 - 15.

因此,为了使您的查询有效,它应该如下所示:

query Orders($input1: PaginationInput, offset: Int) {