首页 > 解决方案 > 如何在 React with Apollo 中执行 GraphQL Query onClick?

问题描述

我正在尝试根据作为字符串传递的特定餐厅来过滤,例如(“鸡肉”、“披萨”等)。foodType

我希望能够onClick在我的React 组件中做到这一点。

我试过用包装<ApolloPriver>器进行查询,但运气不佳。

FoodType.tsx

export const FoodTypes: React.SFC = () => {
  return (
    <div className="food-types">
      <ul className="food-type-list">
        <li className="food-type-item" onClick={async () => {
                const { data } = await client.query({
                  query: FOODTYPE_QUERY,
                  variables: { foodType: "Pizza" }
                })}}>Pizza</li>
        <li className="food-type-item" onClick={}>Chicken</li>
        <li className="food-type-item" onClick={}>Indian</li>
        <li className="food-type-item" onClick={}>Chinese</li>
        <li className="food-type-item" onClick={}>English</li>
        <li className="food-type-item" onClick={}>Fish & Chips</li>
        <li className="food-type-item" onClick={}>Kebab</li>
        <li className="food-type-item" onClick={}>Curry</li>
        <li className="food-type-item" onClick={}>Caribbean</li>
      </ul>
)}

我要传递的 GQL 查询

const FOODTYPE_QUERY = gql`
  query foodTypeQuery($foodType: String!) {
    getFoodType(foodType: $foodType) {
      id
      name
      address
      foodType
    }
  }
`;

我目前如何展示 中的所有餐馆FoodTypes.tsx。这是我希望onClick上面按钮的结果。

<div className={"EateryWrapper"}>
        <ApolloProvider client={client}>
          <Query query={EATERY_QUERY}>
            {({ loading, data }: any) => {
              if (loading) return "Loading...";
              const { eateries } = data;
              return eateries.map((eatery: any) => (
                <EateryItem
                  key={eatery.id}
                  id={eatery.id}
                  name={eatery.name}
                  address={eatery.address}
                  foodType={eatery.foodType}
                />
              ));
            }}
          </Query>
        </ApolloProvider>
      </div>

整体FoodTypes.tsx

import React from "react";
import "./FoodTypes.scss";
import { ApolloProvider, Query } from "react-apollo";
import { gql } from "apollo-boost";

import { client } from "../..";
import { EateryItem } from "../Eatery/EateryItem";

const EATERY_QUERY = gql`
  {
    eateries {
      id
      name
      address
      foodType
    }
  }
`;

const FOODTYPE_QUERY = gql`
  query foodTypeQuery($foodType: String!) {
    getFoodType(foodType: $foodType) {
      id
      name
      address
      foodType
    }
  }
`;

export const FoodTypes: React.SFC = () => {
  return (
    <div className="food-types">
      <ul className="food-type-list">
        <li className="food-type-item" onClick={async () => {
          const { data } = await client.query({
            query: FOODTYPE_QUERY,
            variables: { foodType: "Pizza" }
          })
          console.log(data)}
        }>Pizza</li>
        <li className="food-type-item">Chicken</li>
        <li className="food-type-item">Indian</li>
        <li className="food-type-item">Chinese</li>
        <li className="food-type-item">English</li>
        <li className="food-type-item">Fish & Chips</li>
        <li className="food-type-item">Kebab</li>
        <li className="food-type-item">Curry</li>
        <li className="food-type-item">Caribbean</li>
      </ul>
      <div className={"EateryWrapper"}>
        <ApolloProvider client={client}>
          <Query query={EATERY_QUERY}>
            {({ loading, data }: any) => {
              if (loading) return "Loading...";
              const { eateries } = data;
              return eateries.map((eatery: any) => (
                <EateryItem
                  key={eatery.id}
                  id={eatery.id}
                  name={eatery.name}
                  address={eatery.address}
                  foodType={eatery.foodType}
                />
              ));
            }}
          </Query>
        </ApolloProvider>
      </div>
    </div>
  );
};

export default FoodTypes;

更新FoodTypes.tsx

import React, { Component, useState } from "react";
import "./FoodTypes.scss";
import { ApolloProvider, Query } from "react-apollo";
import { gql } from "apollo-boost";

import { client } from "../..";
import { EateryItem } from "../Eatery/EateryItem";

const EATERY_QUERY = gql`
  {
    eateries {
      id
      name
      address
      foodType
    }
  }
`;

const FOODTYPE_QUERY = gql`
  query foodTypeQuery($foodType: String!) {
    getFoodType(foodType: $foodType) {
      id
      name
      address
      foodType
    }
  }
`;

type foodTypeFilterProps = {
  foodTypeName: String
}

export const FoodTypes: React.SFC = () => {
  return (
    <div className="food-types">
      <ul className="food-type-list">
        <FoodTypeFilter foodTypeName={'Italian'}/>
        <FoodTypeFilter foodTypeName={'Pizza'}/>
        <FoodTypeFilter foodTypeName={'Chicken'}/>
        <FoodTypeFilter foodTypeName={'Indian'}/>
        <FoodTypeFilter foodTypeName={'Chinese'}/>
        <FoodTypeFilter foodTypeName={'English'}/>
        <FoodTypeFilter foodTypeName={'Fish & Chips'}/>
        <FoodTypeFilter foodTypeName={'Kebab'}/>
        <FoodTypeFilter foodTypeName={'Curry'}/>
        <FoodTypeFilter foodTypeName={'Caribbean'}/>
      </ul>
      <div className={"EateryWrapper"}>
        <ApolloProvider client={client}>
          <Query query={EATERY_QUERY}>
            {({ loading, data }: any) => {
              if (loading) return "Loading...";
              const { eateries } = data;
              return eateries.map((eatery: any) => (
                <EateryItem
                  key={eatery.id}
                  id={eatery.id}
                  name={eatery.name}
                  address={eatery.address}
                  foodType={eatery.foodType}
                />
                ));
            }}
          </Query>
        </ApolloProvider>
      </div>
    </div>
  );
};

const FoodTypeFilter: React.FunctionComponent<foodTypeFilterProps> = props => {
  const [foodType, setFoodType] = useState(props.foodTypeName);
  return(
    <li className="food-type-item" onClick={async () => {
      const { data } = await client.query({
        query: FOODTYPE_QUERY,
        variables: { foodType: props.foodTypeName }
      })
      setFoodType(foodType);
      }}>{foodType}
      </li>
  )
}

export default FoodTypes;

让上述元素使用 onClick 上方的 GQL 查询的最佳方法是什么?

标签: javascriptreactjstypescriptgraphqlapollo

解决方案


首先,我建议您将FoodTypes组件更改为 React 组件,以便能够将从您的 graphql 查询返回的数据存储在state

export class classFoodTypes extends React.Component 

现在,在您的classFoodTypes组件中,您可以setState在获取数据后调用:

<li className="food-type-item" onClick={async () => {
                const { data } = await client.query({
                  query: FOODTYPE_QUERY,
                  variables: { foodType: "Pizza" }
                })}
                this.setState({eateries: data})}>Pizza</li>

从那里,您可以显示您的数据state

            <EateryItem
              key={this.state.eateries.id}
              id={this.state.eateries.id}
              name={this.state.eateries.name}
              address={this.state.eateries.address}
              foodType={this.state.eateries.foodType}
            />

我不会完成其余组件的实现,以便您可以练习实现,但这种模式应该有助于引导您朝着正确的方向前进。让我知道您是否在途中遇到困难。


推荐阅读