2017-11-21 11 views
0

고객의 테이블 구성 요소를 제공하기 위해 apollo를 구현하려고합니다.React-apollo v2 - Youshido GraphQlBundle - 두 개의 쿼리를 동시에 다시 입력하십시오.

import CustomersTable from 'components/Customer/CustomersTable'; 

이 테이블은 필터링 가능, 정렬 가능 및 페이지 매김이어야합니다. MySQL 테이블에 200.000 명의 고객이 있습니다. 이것이 필터, 정렬 및 페이지 매김이 서버 측에서 계산되는 이유입니다. 을 별도로 쿼리해야합니다. 고객은 페이지 매김의 총 개수와 고객 목록을 필요로합니다. filtersInput 변경할 때

import GET_CUSTOMERS_PAGINATED_QUERY from './getCustomersPaginated.graphql'; 
import GET_CUSTOMERS_PAGINATED_COUNT_QUERY from './getCustomersPaginatedCount.graphql'; 

의외로 다시 반입 함수 회불린다. 첫 번째는 올바른 새로운 변수이고, 두 번째는 초기 변수입니다. 따라서 총 고객 수는 이며,을 덮어 씁니다. (아무 오류) here을 조언을 같이

const initialFilters = { filterId: null, filterSiren: null, filterName: null, filterEmail: null, }; const getCustomersPaginatedCountOptions = { name: 'customersPaginatedCount', options() { return { variables: { ...initialFilters, }, fetchPolicy: 'network-only', }; }, props({ customersPaginatedCount }) { return { customersPaginatedCount: customersPaginatedCount, }; }, }; const getCustomersPaginatedOptions = { name: 'customersPaginated', options({ offset, limit }) { return { variables: { offset: offset, limit: limit, ...initialFilters, }, fetchPolicy: 'network-only', }; }, props({ customersPaginated }) { return { customersPaginated: customersPaginated, }; }, }; 

이 두 쿼리

이 구성되어있다 :

이 이
@compose(
    graphql(GET_CUSTOMERS_PAGINATED_QUERY, getCustomersPaginatedOptions), 
    graphql(GET_CUSTOMERS_PAGINATED_COUNT_QUERY, getCustomersPaginatedCountOptions), 
) 
export default class CustomersTableContainer extends React.PureComponent { 

    state = { 
    offset: this.props.offset, 
    limit: this.props.limit, 
    pageSize: 10, 
    currentPage: 0, 
    filters: initialFilters, 
    currentOnFilterChangeTimeoutID: null, 
    }; 

    constructor(props) { 
    super(props); 

    this.onCurrentPageChange = this.onCurrentPageChange.bind(this); 
    this.onFiltersChange = this.onFiltersChange.bind(this); 
    } 

    onCurrentPageChange(newPage) { 
    const { customersPaginated } = this.props; 
    const { limit, filters } = this.state; 

    customersPaginated.refetch({ 
     offset: newPage * limit, 
     ...filters, 
    }); 

    this.setState({ currentPage: newPage }); 
    } 

    onFiltersChange(args) { 
    const { customersPaginated, customersPaginatedCount } = this.props; 
    const { limit } = this.state; 

    const newFilters = Object.assign({}, initialFilters); 
    for (const i in args) { 
     newFilters['filter' + ucfirst(args[i].columnName)] = args[i].value; 
    } 

    customersPaginated.refetch({ 
     offset: 0 * limit, 
     ...newFilters, 
    }); 

    // --- >> THE REFETCH FUNCTION IS TRIGGERED TWICE HERE ! << --- 
    customersPaginatedCount.refetch({ 
     ...newFilters, 
    }); 

    // here 'test' is displayed once, so onFiltersChange is called once too as expected 
    console.log('test'); 


    this.setState({ 
     currentPage: 0, 
     filters: newFilters, 
    }); 
    } 

    render() { 
    const { customersPaginated, customersPaginatedCount } = this.props; 
    const { currentPage, pageSize } = this.state; 

    if (customersPaginated.error) console.error(customersPaginated.error); 
    if (customersPaginatedCount.error) console.error(customersPaginatedCount.error); 


    return (
     <div> 
     {(customersPaginated.error || customersPaginatedCount.error) && (
      <Typography color="error" gutterBottom> 
      Une erreur est survenue. 
      </Typography> 
     )} 
     <div> 
      <CustomersTable 
      customers={customersPaginated.customersPaginated} 
      currentPage={currentPage} 
      onCurrentPageChange={this.onCurrentPageChange} 
      onFiltersChange={this.onFiltersChange} 
      pageSize={pageSize} 
      totalCount={customersPaginatedCount.customersPaginatedCount || 0} 
      /> 
      {(customersPaginated.loading || customersPaginatedCount.loading) && <Loading />} 
     </div> 
     </div> 
    ); 
    } 

    static propTypes = { 
    customersPaginated: PropTypes.object.isRequired, 
    customersPaginatedCount: PropTypes.object.isRequired, 
    offset: PropTypes.number.isRequired, 
    limit: PropTypes.number.isRequired, 
    }; 
} 
가 예상되는 동작의 구성 요소로드에

내 콘솔 로그 :

{variables: {filterId: null, filterSiren: null, filterName: null, filterEmail: null}, operationName: "getCustomersPaginatedCount" 
{variables: {filterId: null, filterSiren: null, filterName: null, filterEmail: null}, operationName: "getCustomersPaginated" 

내 콘솔 로그온 필터 입력 변경 예기치 않은 동작 :

{variables: {filterId: null, filterSiren: null, filterName: "example of customer name", filterEmail: null}, operationName: "getCustomersPaginated" 
{variables: {filterId: null, filterSiren: null, filterName: "example of customer name", filterEmail: null}, operationName: "getCustomersPaginatedCount" 
{variables: {filterId: null, filterSiren: null, filterName: null, filterEmail: null}, operationName: "getCustomersPaginatedCount" 

getCustomersPaginated.graphql :

query getCustomersPaginated(
    $filterId: Int, 
    $filterSiren: String, 
    $filterName: String, 
    $filterEmail: String, 
    $offset: Int, 
    $limit: Int 
) { 
    customersPaginated(
     filterId: $filterId, 
     filterSiren: $filterSiren, 
     filterName: $filterName, 
     filterEmail: $filterEmail, 
     offset: $offset, 
     limit: $limit 
    ) { 
    id 
    name 
    siren 
    email 
    activity { 
     id 
     name 
     shortName 
     code 
    } 
    salesFollower { 
     id 
     username 
     firstname 
     lastname 
     email 
     initials 
     enabled 
    } 
    customerGroup { 
     id 
     name 
     code 
     enabled 
    } 
    coreBusiness { 
     id 
     name 
     codeApe 
     codeNaf 
    } 
    } 
} 

getCustomersPaginatedCount.graphql :

query getCustomersPaginatedCount(
    $filterId: Int, 
    $filterSiren: String, 
    $filterName: String, 
    $filterEmail: String 
) { 
    customersPaginatedCount(
    filterId: $filterId, 
    filterSiren: $filterSiren, 
    filterName: $filterName, 
    filterEmail: $filterEmail, 
) 
} 

내 ENVIRONNEMENT :

전면 : 반응 - 아폴로 돌아 가기

와 reactjs : 나는 시작 Symfony3와 PHP 7 Youshido\GraphQLBundle

는 올해 반응이 달에 아폴로. 어쩌면 나는 더 나은 방법이 있을지도 모르는 버그가있을 수도 있습니다 (변경 사항을 보지 않고 1.0.2에서 1.0.3으로 아폴로 클라이언트 프리셋을 업데이트했습니다). Youshido 측에서 고객의 목록과 고객 수를 하나의 쿼리로 가져올 수있는 해결책이있을 수도 있습니다.

도움 주셔서 감사합니다.

답변

0

경우에 따라 다시 페치 기능이 필요하지 않은 경우도 있습니다. @stelmakh에게 도움을 주신 덕분에 issue !!

내 새로운 코드 : 아이 :

import React from 'react'; 
import PropTypes from 'prop-types'; 
import { compose, graphql } from 'react-apollo'; 
import { ucfirst } from 'utils/string'; 

import CustomersTable from 'components/Customer/CustomersTable'; 
import Typography from 'material-ui/Typography'; 

import Loading from 'components/Loading/Loading'; 

import GET_CUSTOMERS_PAGINATED_QUERY from './getCustomersPaginated.graphql'; 
import GET_CUSTOMERS_PAGINATED_COUNT_QUERY from './getCustomersPaginatedCount.graphql'; 


const getCustomersPaginatedCountOptions = { 
    name: 'customersPaginatedCount', 
    options({ variables }) { 
    return { 
     variables: variables, 
     fetchPolicy: 'network-only', 
    }; 
    }, 
    props({ customersPaginatedCount }) { 
    return { customersPaginatedCount: customersPaginatedCount }; 
    }, 
}; 
const getCustomersPaginatedOptions = { 
    name: 'customersPaginated', 
    options({ variables }) { 
    return { 
     variables: variables, 
     fetchPolicy: 'network-only', 
    }; 
    }, 
    props({ customersPaginated }) { 
    return { customersPaginated: customersPaginated }; 
    }, 
}; 

@compose(
    graphql(GET_CUSTOMERS_PAGINATED_QUERY, getCustomersPaginatedOptions), 
    graphql(GET_CUSTOMERS_PAGINATED_COUNT_QUERY, getCustomersPaginatedCountOptions), 
) 
export default class CustomersTableContainer extends React.PureComponent { 

    state = { 
    currentOnFilterChangeTimeoutID: null, 
    }; 

    constructor(props) { 
    super(props); 

    this.onCurrentPageChange = this.onCurrentPageChange.bind(this); 
    this.onSortingChange = this.onSortingChange.bind(this); 
    this.onFiltersChange = this.onFiltersChange.bind(this); 
    } 

    onCurrentPageChange(newPage) { 
    const { onChange, variables } = this.props; 

    onChange({ 
     currentPage: newPage, 
     'offset': newPage * variables.limit, 
    }); 
    } 

    onFiltersChange(args) { 
    clearTimeout(this.state.currentOnFilterChangeTimeoutID); 

    const newCurrentOnFilterChangeTimeoutID = setTimeout(() => { 
     const { onChange, variables } = this.props; 

     const newVariables = Object.assign({}, variables); 

     if (args.length > 0) { 
     for (const i in args) { 
      newVariables['filter' + ucfirst(args[i].columnName)] = args[i].value; 
     } 
     } else { 
     for (const i in newVariables) { 
      if (i.substr(0, 6) === 'filter') newVariables[i] = null; 
     } 
     } 

     onChange({ 
     ...newVariables, 
     'currentPage': 0, 
     'offset': 0 * variables.limit, 
     }); 
    }, 1000); 

    this.setState({ currentOnFilterChangeTimeoutID: newCurrentOnFilterChangeTimeoutID }); 
    } 

    render() { 
    const { variables, customersPaginated, customersPaginatedCount } = this.props; 

    if (customersPaginated.error) console.error(customersPaginated.error); 
    if (customersPaginatedCount.error) console.error(customersPaginatedCount.error); 


    return (
     <div> 
     {(customersPaginated.error || customersPaginatedCount.error) && (
      <Typography color="error" gutterBottom> 
      Une erreur est survenue. 
      </Typography> 
     )} 
     <div> 
      <CustomersTable 
      customers={customersPaginated.customersPaginated} 
      currentPage={variables.currentPage} 
      onCurrentPageChange={this.onCurrentPageChange} 
      onSortingChange={this.onSortingChange} 
      onFiltersChange={this.onFiltersChange} 
      pageSize={variables.pageSize} 
      totalCount={customersPaginatedCount.customersPaginatedCount || 0} 
      /> 
      {(customersPaginated.loading || customersPaginatedCount.loading) && <Loading />} 
     </div> 
     </div> 
    ); 
    } 

    static propTypes = { 
    customersPaginated: PropTypes.object.isRequired, 
    customersPaginatedCount: PropTypes.object.isRequired, 
    variables: PropTypes.object.isRequired, 
    onChange: PropTypes.func.isRequired, 
    }; 
} 

부모 :

import React from 'react'; 

import Typography from 'material-ui/Typography'; 
import Button from 'material-ui/Button'; 
import AddIcon from 'material-ui-icons/Add'; 

import CustomersTableContainer from 'containers/Customer/CustomersTableContainer'; 

export default class CustomersPage extends React.PureComponent { 

    constructor(props) { 
    super(props); 

    this.state = { 
     customersTableVariables: { 
     filterId: null, 
     filterSiren: null, 
     filterName: null, 
     filterEmail: null, 
     pageSize: 10, 
     currentPage: 0, 
     offset: 0, 
     limit: 10, 
     }, 
    }; 

    this.onCustomersChange = this.onCustomersChange.bind(this); 
    } 

    onCustomersChange (newVariables) { 
    this.setState({ 
     customersTableVariables: Object.assign({}, this.state.customersTableVariables, newVariables) 
    }); 
    } 

    render() { 
    const { customersTableVariables } = this.state; 
    return (
     <div> 
     <Typography align="right"> 
      <Button fab color="primary" aria-label="add" href="/customer/new"> 
      <AddIcon /> 
      </Button> 
     </Typography> 
     <Typography type="title" gutterBottom> 
      Clients/Prospects 
     </Typography> 
     <CustomersTableContainer variables={customersTableVariables} onChange={this.onCustomersChange} /> 
     </div> 
    ); 
    } 
}