2017-11-21 13 views
0

私は顧客のテーブルコンポーネントにフィードするためにapolloを実装しようとしています。React-apollo v2 - Youshido GraphQlBundle - 2つのクエリを同時に再入力する

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'; 

予期せず、再フェッチ機能は、二回と呼ばれています。正しい新しい変数で初めて、そして初期変数で2番目の変数。したがって、合計顧客数はで、に上書きされます。

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, 
    }; 
    }, 
}; 

これらの2つのクエリを(エラーなしの場合)hereをアドバイスとして構成されている:予想される挙動の成分負荷に

@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, 
) 
} 

マイエンバイロメント:

フロント:反応 - アポロ戻る

とreactjs:私は始めSymfony3とPHP 7とYoushido\GraphQLBundle

は、今年を反応させ、今月アポロ。 おそらくもっと良い方法があるかもしれないし、おそらくバグがあるかもしれません(私はapollo-client-presetを1.0.2から1.0.3に更新していません)。 Youshido側には、顧客のリストと顧客数を1つのクエリで取得できるソリューションがあるかもしれません。

ありがとうございました。

答えて

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> 
    ); 
    } 
} 
関連する問題