如何在反应钩子中使用graphql钩子集成多个客户端

Posted

技术标签:

【中文标题】如何在反应钩子中使用graphql钩子集成多个客户端【英文标题】:How to integrate Multiple clients using graphql hooks in react hooks 【发布时间】:2020-05-15 18:37:04 【问题描述】:

我想在我的 react-hooks 应用程序中集成多个客户端。我通过 Apollo 客户端使用 graphql-hooks 我们有一个模块来集成多个客户端

以下是 Apollo graphql 多客户端链接

    `https://www.npmjs.com/package/@titelmedia/react-apollo-multiple-clients`

以下我正在使用 graphql 钩子

https://www.npmjs.com/package/graphql-hooks

我们如何为 graphql-hooks 实现相同的目标?

我的要求取决于单选按钮的选择,我需要在使用多个客户端的一个组件中在这些多个客户端之间进行切换。 在我的应用程序中,我使用的是graphql-hook,我们将组件包装到客户端,这里相同的组件具有功能,其中根据选择的单选按钮之一,客户端必须切换。我有一个客户端,但需要集成多个我用谷歌搜索的客户,但我没有找到,所以在这里提出了质疑。 这可能吗? 哪位大神可以帮忙看看

【问题讨论】:

我不确定我是否理解您的问题。看起来应该可以多次调用new GraphQLClient() 来获取多个graphql-hooks 客户端,就像你可以多次调用new ApolloClient() 来获取多个apollo 客户端一样。还有比这更多的吗? 是的,在我的应用程序中,我使用的是 graphql-hook,我们将组件包装到客户端,这里相同的组件具有功能,其中取决于选择的单选按钮之一,客户端必须切换。我我有一个客户,但需要整合多个客户我用谷歌搜索但我没有找到所以在这里提出质疑。 是的,在这种情况下,多次调用new GraphQLClient() 以获得多个graphql 客户端可能没问题。 哪个GraphQLClient?它在哪里?? @MohammadReza 使用 graphql 工具在那里你会发现 【参考方案1】:

我们可以多次使用 new GraphQLClient() 来获取多个graphql客户端

【讨论】:

【参考方案2】:

这是一个很好的方法,你可以遵循它:https://www.loudnoises.us/next-js-two-apollo-clients-two-graphql-data-sources-the-easy-way/

【讨论】:

【参考方案3】:

我有两个中间件 graphql 服务器正在运行。一个用于应用程序,一个用于分析。根据我的需要,我以两种不同的方式进行操作,如下所示...

CubeClient.jsx

import  ApolloClient  from "apollo-client";
import  InMemoryCache  from "apollo-cache-inmemory";
import  SchemaLink  from "apollo-link-schema";
import  makeExecutableSchema  from "graphql-tools";

const cache = new InMemoryCache();
const defaultDashboardItems = ["vizState":"\"query\":\"measures\":[\"Product.count\"],\"timeDimensions\":[\"dimension\":\"Product.createdAt\"],\"dimensions\":[\"Producttype.name\"],\"filters\":[],\"order\":,\"chartType\":\"bar\",\"orderMembers\":[\"id\":\"Product.count\",\"title\":\"Product Count\",\"order\":\"none\",\"id\":\"Producttype.name\",\"title\":\"Producttype Name\",\"order\":\"none\",\"id\":\"Product.createdAt\",\"title\":\"Product Created at\",\"order\":\"none\"],\"pivotConfig\":\"x\":[\"Producttype.name\"],\"y\":[\"measures\"],\"fillMissingDates\":true,\"joinDateRange\":false,\"shouldApplyHeuristicOrder\":true,\"sessionGranularity\":null","name":"Product Types","id":"2","layout":"\"x\":0,\"y\":0,\"w\":24,\"h\":8","vizState":"\"query\":\"measures\":[\"Sale.total\"],\"timeDimensions\":[\"dimension\":\"Sale.createdAt\",\"granularity\":\"day\"],\"dimensions\":[\"Customer.firstname\"],\"order\":\"Sale.total\":\"desc\",\"chartType\":\"area\",\"orderMembers\":[\"id\":\"Sale.total\",\"title\":\"Sale Total\",\"order\":\"desc\",\"id\":\"Customer.firstname\",\"title\":\"Customer Firstname\",\"order\":\"none\",\"id\":\"Sale.createdAt\",\"title\":\"Sale Created at\",\"order\":\"none\"],\"pivotConfig\":\"x\":[\"Sale.createdAt.day\"],\"y\":[\"Customer.firstname\",\"measures\"],\"fillMissingDates\":true,\"joinDateRange\":false,\"shouldApplyHeuristicOrder\":true","name":"Sale Total","id":"3","layout":"\"x\":0,\"y\":8,\"w\":24,\"h\":8"]

export function getCubeClient(location)

  const getDashboardItems = () => 
    //   return JSON.parse(window.localStorage.getItem("dashboardItems")) || defaultDashboardItems;
    return defaultDashboardItems
  

  const setDashboardItems = items => 
    return  window.localStorage.setItem("dashboardItems", JSON.stringify(items));
  

  const nextId = () => 
    const currentId = parseInt(window.localStorage.getItem("dashboardIdCounter"), 10) || 1;
    window.localStorage.setItem("dashboardIdCounter", currentId + 1);
    return currentId.toString();
  ;

  const toApolloItem = i => ( ...i, __typename: "DashboardItem" );

  const typeDefs = `
    type DashboardItem 
      id: String!
      layout: String
      vizState: String
      name: String
    

    input DashboardItemInput 
      layout: String
      vizState: String
      name: String
    

    type Query 
      dashboardItems: [DashboardItem]
      dashboardItem(id: String!): DashboardItem
    

    type Mutation 
      createDashboardItem(input: DashboardItemInput): DashboardItem
      updateDashboardItem(id: String!, input: DashboardItemInput): DashboardItem
      deleteDashboardItem(id: String!): DashboardItem
    
  `;
  const schema = makeExecutableSchema(
    typeDefs,
    resolvers: 
      Query: 
        dashboardItems() 
          const dashboardItems = getDashboardItems();
          return dashboardItems.map(toApolloItem);
        ,

        dashboardItem(_,  id ) 
          const dashboardItems = getDashboardItems();
          return toApolloItem(dashboardItems.find(i => i.id.toString() === id));
        
      ,
      Mutation: 
        createDashboardItem: (_,  input:  ...item  ) => 
          const dashboardItems = getDashboardItems();
          item =  ...item, id: nextId(), layout: JSON.stringify() ;
          dashboardItems.push(item);
          setDashboardItems(dashboardItems);
          return toApolloItem(item);
        ,
        updateDashboardItem: (_,  id, input:  ...item  ) => 
          const dashboardItems = getDashboardItems();
          item = Object.keys(item)
            .filter(k => !!item[k])
            .map(k => (
              [k]: item[k]
            ))
            .reduce((a, b) => ( ...a, ...b ), );
          const index = dashboardItems.findIndex(i => i.id.toString() === id);
          dashboardItems[index] =  ...dashboardItems[index], ...item ;
          setDashboardItems(dashboardItems);
          return toApolloItem(dashboardItems[index]);
        ,
        deleteDashboardItem: (_,  id ) => 
          const dashboardItems = getDashboardItems();
          const index = dashboardItems.findIndex(i => i.id.toString() === id);
          const [removedItem] = dashboardItems.splice(index, 1);
          setDashboardItems(dashboardItems);
          return toApolloItem(removedItem);
        
      
    
  );

  return  new ApolloClient(
    cache,
    uri: "http://localhost:4000",
    link: new SchemaLink(
      schema
    )
  );

仪表板.jsx

import  getCubeClient  from './CubeClient';
import  Query  from "react-apollo";

let cubeClient = getCubeClient()

const Dashboard = () => 
  const dashboardItem = item => (
    <div key=item.id data-grid=defaultLayout(item)>
      <DashboardItem key=item.id itemId=item.id title=item.name>
        <ChartRenderer vizState=item.vizState />
      </DashboardItem>
    </div>
  );

return(
  <Query query=GET_DASHBOARD_ITEMS client=cubeClient>
    ( error, loading, data ) => 
      if (error) return <div>"Error!"</div>;
      if (loading) return (
            <div className="alignCenter">
              <Spinner color="#be97e8" size=48 sizeUnit="px" />
            </div>
          );
      if (data) 
        return (<DashboardView t=translate dashboardItems=data && data.dashboardItems>
          data && data.dashboardItems.map(deserializeItem).map(dashboardItem)
        </DashboardView>)
       else 
        return <div></div>
      
    
  </Query>
  )
;

探索.jsx

import  useQuery  from "@apollo/react-hooks";
import  withRouter  from "react-router-dom";
import ExploreQueryBuilder from "../components/QueryBuilder/ExploreQueryBuilder";
import  GET_DASHBOARD_ITEM  from "../graphql/queries";
import TitleModal from "../components/TitleModal.js";
import  isQueryPresent  from "@cubejs-client/react";
import PageHeader from "../components/PageHeader.js";
import ExploreTitle from "../components/ExploreTitle.js";
import  PageLayout  from '@gqlapp/look-client-react';
import Helmet from 'react-helmet';
import  translate  from '@gqlapp/i18n-client-react';
import  FontAwesomeIcon  from '@fortawesome/react-fontawesome';
import  faAngleRight, faTrashAlt, faPlusCircle  from '@fortawesome/free-solid-svg-icons';
import settings from '@gqlapp/config';
import PropTypes from 'prop-types';
import  getCubeClient  from './CubeClient';

let cubeClient = getCubeClient()

const Explore = withRouter(( history, location,t ) => 
  const [addingToDashboard, setAddingToDashboard] = useState(false);
  const params = new URLSearchParams(location.search);
  const itemId = params.get("itemId");
  const  loading, error, data  = useQuery(GET_DASHBOARD_ITEM, 
    client: cubeClient,
    variables: 
      id: itemId
    ,
    skip: !itemId
  );

Titlemodal.jsx

import React from "react";
import  Modal, Input  from "antd";
import  useMutation  from "@apollo/react-hooks";
import  GET_DASHBOARD_ITEMS  from "../graphql/queries";
import 
  CREATE_DASHBOARD_ITEM,
  UPDATE_DASHBOARD_ITEM
 from "../graphql/mutations";
import  getCubeClient  from '../containers/CubeClient';

let cubeClient = getCubeClient()

const TitleModal = (
  history,
  itemId,
  titleModalVisible,
  setTitleModalVisible,
  setAddingToDashboard,
  finalVizState,
  setTitle,
  finalTitle
) => 
  const [addDashboardItem] = useMutation(CREATE_DASHBOARD_ITEM, 
    client: cubeClient,
    refetchQueries: [
      
        query: GET_DASHBOARD_ITEMS
      
    ]
  );
  const [updateDashboardItem] = useMutation(UPDATE_DASHBOARD_ITEM, 
    client: cubeClient,
    refetchQueries: [
      
        query: GET_DASHBOARD_ITEMS
      
    ]
  );

查询和突变.js

import gql from "graphql-tag";

export const GET_DASHBOARD_ITEMS = gql`
  query GetDashboardItems 
    dashboardItems 
      id
      layout
      vizState
      name
    
  
`;

export const GET_DASHBOARD_ITEM = gql`
  query GetDashboardItem($id: String!) 
    dashboardItem(id: $id) 
      id
      layout
      vizState
      name
    
  
`;

export const CREATE_DASHBOARD_ITEM = gql`
  mutation CreateDashboardItem($input: DashboardItemInput) 
    createDashboardItem(input: $input) 
      id
      layout
      vizState
      name
    
  
`;

export const UPDATE_DASHBOARD_ITEM = gql`
  mutation UpdateDashboardItem($id: String!, $input: DashboardItemInput) 
    updateDashboardItem(id: $id, input: $input) 
      id
      layout
      vizState
      name
    
  
`;

export const DELETE_DASHBOARD_ITEM = gql`
  mutation DeleteDashboardItem($id: String!) 
    deleteDashboardItem(id: $id) 
      id
      layout
      vizState
      name
    
  
`;

【讨论】:

以上是关于如何在反应钩子中使用graphql钩子集成多个客户端的主要内容,如果未能解决你的问题,请参考以下文章

Apollo 客户端使用 GET 请求的查询反应钩子

如何使用打字稿中的反应钩子设置graphql数据?

使用钩子从反应中调用 GraphQL 突变的正确方法

使用 null GraphQL 数据反应原生钩子

@apollo/client 反应钩子 useQuery() 数据未定义

如何使用反应钩子实现多个复选框