2017-03-02 20 views
5

Tôi đang xây dựng một giao diện người dùng cho phép người dùng chọn truy vấn "hoạt động" từ danh sách truy vấn tĩnh và làm phẳng kết quả được hiển thị trong bảng. Cách tốt nhất để vượt qua truy vấn GraphQL từ một thành phần bậc cao hơn vào một thành phần con lồng nhau là gì?Tự động đặt truy vấn GraphQL cho các thành phần React với Apollo Client

Hầu hết tài liệu/giải pháp mà tôi đã thấy tập trung vào việc liên kết truy vấn tĩnh với điều kiện động từ trạng thái thành phần đến thành phần, sẽ không hoạt động cho mục đích của tôi vì các truy vấn tĩnh khác nhau có các trường khác nhau và truy vấn nút khác nhau loại.

Phương pháp hay nhất/được đề xuất ở đây là gì? Tôi cảm thấy như đây không phải là một trường hợp sử dụng rất độc đáo, nhưng tôi dường như không thể tìm thấy bất kỳ ví dụ nào có thể làm điều tương tự.

Tôi đang sử dụng Apollo-Client/Redux làm cửa hàng phụ của khách hàng của mình.

dưới đây là phác thảo sơ bộ các thành phần:

class GridViewPage extends React.Component{ 
 
    constructor(props, context) { 
 
    super(props, context); 
 
    this.state = { 
 
     activeQuery = ... Stores the selected query ... 
 
    }; 
 
    } 
 

 
    render() { 
 
    return (
 
     <div className="gridContainer"> 
 
     ...Component here allows users to select a query from active list and saves it/it's ID/Index to the state... 
 

 
     <Panel collapsible> 
 
     ...Some toolbar components... 
 
     </Panel> 
 
     ...Component here displays the result of the query (Ideally by receiving the query or the result of as a prop?)... 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
GridViewPage.propTypes = { 
 
    grids: PropTypes.array.isRequired, 
 
    actions: PropTypes.object.isRequired 
 
}; 
 

 
function mapStateToProps(state, ownProps) { 
 
    return { 
 
     // Receives list of available queries as a prop 
 
     grids: state.grids 
 
    }; 
 
}

Trả lời

2

Chúng ta hãy, ví dụ, các thành phần sau đây:

ProfileWithData.js

import React, { Component, PropTypes } from 'react'; 
import { graphql } from 'react-apollo'; 
import gql from 'graphql-tag'; 

class Profile extends Component { ... } 
Profile.propTypes = { 
    data: PropTypes.shape({ 
    loading: PropTypes.bool.isRequired, 
    currentUser: PropTypes.object, 
    }).isRequired, 
}; 

// We use the gql tag to parse our query string into a query document 
const CurrentUserForLayout = gql` 
    query CurrentUserForLayout { 
    currentUser { 
     login 
     avatar_url 
    } 
    } 
`; 

const ProfileWithData = graphql(CurrentUserForLayout)(Profile); 

Nó sẽ được khá dễ dàng gói nó với một higher order component:

Profile.js

import React, { Component, PropTypes } from 'react'; 

export class Profile extends Component { ... } 
Profile.propTypes = { 
    data: PropTypes.shape({ 
    loading: PropTypes.bool.isRequired, 
    currentUser: PropTypes.object, 
    }).isRequired, 
}; 

createProfileWithData.js

import React, { Component, PropTypes } from 'react'; 
import { graphql } from 'react-apollo'; 
import { Profile } from './Profile' 

export default function createProfileWithData(query) => { 
    return graphql(query)(Profile); 
} 

Sau đó bạn sẽ sử dụng nó như thế này:

Page.js

import React, { Component, PropTypes } from 'react'; 
import gql from 'graphql-tag'; 
import createProfileWithData from './createProfileWithData'; 

class Page extends Component { 

    renderProfileWithData() { 

     const { textQuery } = this.props; 
     // Simplest way, though you can call gql as a function too 
     const graphQLQuery = gql`${textQuery}`; 

     const profileWithDataType = createProfileWithData(graphQLQuery); 

     return (
     <profileWithDataType /> 
    ); 
    } 

    render() { 

    return (<div> 
       .. 
       {this.renderProfileWithData()} 
       .. 
      </div>) 
    } 

} 

Profile.propTypes = { 
    textQuery: PropTypes.string.isRequired, 
}; 

Tôi nghĩ bạn có được điểm.

Tất nhiên, tiểu sử của bạn sẽ không nhận được props.data.currentUser, thay vì đó sẽ là props.data.* tùy thuộc vào truy vấn gốc và bạn sẽ xử lý nó một cách thích hợp tùy thuộc vào nội dung.

Lưu ý: điều này được viết trực tiếp trong Stack Overflow, vì vậy nếu bạn gặp phải bất kỳ sự cố nào - lmk và tôi sẽ khắc phục.

+0

Cảm ơn! Đã bắt đầu áp dụng mô hình này trong dự án và tôi nghĩ tôi sẽ làm cho nó hoạt động sau cùng. Một lỗi ngay lập tức mà tôi gặp phải là 'const profileWithDataType = createProfileWithData (graphQLQuery);' trả về một kiểu hàm, và do đó không nhấn hàm 'render()' khi lồng bên trong '{this.renderProfileWithData()}'? Đây có thể là vấn đề về cú pháp trên mã của tôi, nhưng suy nghĩ đáng nói đến. – Mike

+0

Vâng, nó có thể là một vấn đề với JSX. Tôi luôn quên nếu cú ​​pháp đó hợp lệ hay không.Bạn cũng có thể làm: '' ' trả về React.createElement (profileWithDataType, {}); '' ' Tôi chắc chắn bạn đã giải quyết vấn đề này ngay bây giờ, vì vậy bản cập nhật sẽ tốt đẹp :) – advance512

+0

Hey! Trên thực tế, tôi đã bỏ qua createProfileWithData.js và đặt truy vấn trực tiếp vào trang trong Page.js với tương đương với 'graphql (truy vấn) (Hồ sơ)' và nó hoạt động :) – Mike

Các vấn đề liên quan