2017-06-30 2 views
0

Im Frontend verwende ich ReactJS und versuche, eine Filteroption in eine Listenansicht einzufügen. Die Listenansicht korrekt Daten von graphql Endpunkt bekommen durch diese graphql Abfrage ausgeben:Funktionsweise der Funktion data.refetch() von react-apollo

query getVideos($filterByBook: ID, $limit: Int!, $after: ID) { 
    videosQuery(filterByBook: $filterByBook, limit: $limit, after: $after) { 
     totalCount 
     edges { 
      cursor 
      node { 
       id 
       title 
       ytDefaultThumbnail 
      } 
     } 
     pageInfo { 
      endCursor 
      hasNextPage 
     } 
    } 
} 

Auf der Anfangslast $filterByBook Variable null gesetzt ist, so gibt die Abfrage korrekt alle Seiten für alle Knoten (Abfrage gibt ein paginierte Ergebnis) . Dann wird durch Klicken auf den Filter (Filter für Buch) eine weitere graphql-Abfrage ausgegeben, die jedoch immer die gleiche data zurückgibt. Hier ist ein Code-Snippet für Filterkomponente

renderFilters() { 
    const { listOfBooksWithChapters, refetch } = this.props; 

    return (
     <Row> 
     <FilterBooks 
      onBookTitleClickParam={(onBookTitleClickParam) => { 
      return refetch({ 
       variables: { 
       limit: 3, 
       after: 0, 
       filterByBook: onBookTitleClickParam 
       } 
      }) 
      }} 
      listOfBooksWithChapters={listOfBooksWithChapters} 
     /> 
     </Row> 
    ) 
    } 

Und hier ist vollständiger Code ohne Importe für die Listenansicht Komponente

class VideoList extends React.Component { 
    constructor(props) { 
    super(props); 

    this.subscription = null; 
    } 

    componentWillUnmount() { 
    if (this.subscription) { 
     // unsubscribe 
     this.subscription(); 
    } 
    } 

    renderVideos() { 
    const { videosQuery } = this.props; 

    return videosQuery.edges.map(({ node: { id, title, ytDefaultThumbnail } }) => { 
     return (
     <Col sm="4" key={id}> 
      <Card> 
      <CardImg top width="100%" src={ytDefaultThumbnail} alt="video image" /> 
      <CardBlock> 
       <CardTitle> 
       <Link 
        className="post-link" 
        to={`/video/${id}`}> 
        {title} 
       </Link> 
       </CardTitle> 
      </CardBlock> 
      </Card> 
     </Col> 
    ); 
    }); 
    } 

    renderLoadMore() { 
    const { videosQuery, loadMoreRows } = this.props; 

    if (videosQuery.pageInfo.hasNextPage) { 
     return (
     <Button id="load-more" color="primary" onClick={loadMoreRows}> 
      Load more ... 
     </Button> 
    ); 
    } 
    } 

    renderFilters() { 
    const { listOfBooksWithChapters, refetch } = this.props; 

    return (
     <Row> 
     <FilterBooks 
      onBookTitleClickParam={(onBookTitleClickParam) => { 
      return refetch({ 
       variables: { 
       limit: 3, 
       after: 0, 
       filterByBook: onBookTitleClickParam 
       } 
      }) 
      }} 
      listOfBooksWithChapters={listOfBooksWithChapters} 
     /> 
     </Row> 
    ) 
    } 


    render() { 
    const { loading, videosQuery } = this.props; 

    if (loading && !videosQuery) { 
     return (
     <div>{ /* loading... */}</div> 
    ); 
    } else { 
     return (
     <div> 
      <Helmet 
      title="Videos list" 
      meta={[{ 
       name: 'description', 
       content: 'List of all videos' 
      }]} /> 
      <h2>Videos</h2> 
      {this.renderFilters()} 
      <Row> 
      {this.renderVideos()} 
      </Row> 
      <div> 
      <small>({videosQuery.edges.length}/{videosQuery.totalCount})</small> 
      </div> 
      {this.renderLoadMore()} 
     </div> 
    ); 
    } 
    } 
} 

export default compose(
    graphql(VIDEOS_QUERY, { 
    options:() => { 
     return { 
     variables: { 
      limit: 3, 
      after: 0, 
      filterByBook: null 
     }, 
     }; 
    }, 
    props: ({ data }) => { 
     const { loading, videosQuery, fetchMore, subscribeToMore, refetch } = data; 
     const loadMoreRows =() => { 
     return fetchMore({ 
      variables: { 
      after: videosQuery.pageInfo.endCursor, 
      }, 
      updateQuery: (previousResult, { fetchMoreResult }) => { 
      const totalCount = fetchMoreResult.videosQuery.totalCount; 
      const newEdges = fetchMoreResult.videosQuery.edges; 
      const pageInfo = fetchMoreResult.videosQuery.pageInfo; 

      return { 
       videosQuery: { 
       totalCount, 
       edges: [...previousResult.videosQuery.edges, ...newEdges], 
       pageInfo, 
       __typename: "VideosQuery" 
       } 
      }; 
      } 
     }); 
     }; 
     return { loading, videosQuery, subscribeToMore, loadMoreRows, refetch }; 
    } 
    }), 
    graphql(LIST_BOOKS_QUERY, { 
    props: ({ data }) => { 
     const { listOfBooksWithChapters } = data; 
     return { listOfBooksWithChapters }; 
    } 
    }), 
)(VideoList); 

Frage:

Warum refetch Funktion Daten zurückgibt, ohne dabei Rechnung neue Variable filterByBook? Wie überprüfe ich, welches Objekt variables ich an die refetch Funktion geliefert habe? Muss ich Daten neu zuordnen, die ich von refetch Funktion zurück an die Komponente props?

EDIT:

fand ich die Art und Weise zu finden, was variable Objekt, das ich auf die Anfrage geliefert und festgestellt, dass variable Objekt auf Filter Ereignis gibt diese Daten

variables:Object 
    after:0 
    limit:3 
     variables:Object 
     after:0 
     filterByBook:"2" 
     limit:3 

Antwort

1

Es scheint, dass refetch Funktion ist nicht dazu gedacht, Daten mit verschiedenen gesetzten Variablen zurückzuholen (siehe discussion).

ich endlich und erfolgreich gelöst mein Problem mit Hilfe von this article

Verwandte Themen