【问题标题】:Passing a string variable prop into useQuery function将字符串变量 prop 传递给 useQuery 函数
【发布时间】:2020-10-03 20:37:42
【问题描述】:

概述

应用最初查询 GraphQL API 并使用 TagsList 呈现“标签”(字符串)。

然后用户可以点击一个标签,然后这个标签被传递给ShortList并被渲染。

我想做什么?

我有第二个名为 GQLSIMILARTAGS 的 GraphQL 查询,它接受一个字符串变量,并在 GQLFuncSecond 中使用 useQuery 调用。我想在用户点击其中一个标签时触发它。

我知道查询可以正常工作,如下所示,硬编码searchLabel 作为变量传入。

<GQLFuncSecond searchLabel={"cloud"} />

问题

当用户单击来自TagsList 的标签时,如何将字符串 (data.tag.label) 传递到此 useQuery 变量中。

我不知道如何将用户选择的标签(当它添加到 ShortList 时)传递到我的 GQLFuncSecond 函数中。

例如,我应该在ShortList 中调用GQLFuncSecond 吗?我该怎么做?

主应用

function WrappedApp(props) {
  const [favourites, setFavourites] = useState([]);

  function GQLFuncSecond(props) {
    const { loading, error, data } = useQuery(GQLSIMILARTAGS, {
      variables: { search_label: props.searchLabel },
    });
    if (loading) return <p>Loading...</p>;
    if (error) return <p>Error :(</p>;

    if (data) return <RelatedTagData data={data.tag} />;
  }

  // add clicked name ID to the favourites array
  const addFavourite = (id) => {
    const newSet = favourites.concat([id]);
    setFavourites(newSet);
  };

  // remove ID from the favourites array
  const deleteFavourite = (id) => {
    const newList = [...favourites.slice(0, id), ...favourites.slice(id + 1)];
    setFavourites(newList);
  };

  return (
    <div>
      <main>
        <GQLFuncSecond searchLabel={"cloud"} />
        <ShortList
          data={props.data}
          favourites={favourites}
          deleteFavourite={deleteFavourite}
        />

        <TagsList
          data={props.data}
          favourites={favourites}
          addFavourite={addFavourite}
        />
      </main>
    </div>
  );
}

export default WrappedApp;

组件

import React, { useState } from "react";
import { useQuery } from "@apollo/react-hooks";
import { GQLSIMILARTAGS } from "./graphclient";

/* ##### Single tag ##### */

const Tag = ({ id, info, handleFavourite }) => (
  <li className={info.count} onClick={() => handleFavourite(id)}>
    {info.label} ({info.tag_related_counts_aggregate.aggregate.count})
  </li>
);

const RelatedTagData = ({ data }) => (
  <div>
    <ul>{data[0].tag_related_counts[0].other_label}</ul>
    <ul>{data[0].tag_related_counts[1].other_label}</ul>
    <ul>{data[0].tag_related_counts[2].other_label}</ul>
    <ul>{data[0].tag_related_counts[3].other_label}</ul>text 
  </div>
);

/* ##### Shortlist ##### */

const ShortList = ({ favourites, data, deleteFavourite, GQLFuncSecond }) => {
  const hasFavourites = favourites.length > 0;
  const favList = favourites.map((fav, i) => {
    return (
      <Tag
        id={i}
        key={i}
        info={data.find((tag) => tag.id === fav)}
        handleFavourite={(id) => deleteFavourite(id)}
      />
    );
  });
  return (
    <div className="favourites">
      <h4>
        {hasFavourites
          ? "Shortlist. Click to remove.."
          : "Click on a tag to shortlist it.."}
      </h4>
      <ul>{favList}</ul>
      {hasFavourites && <hr />}
    </div>
  );
};

/* ##### Tag list ##### */

const TagsList = ({ data, addFavourite }) => {
  // Gather list of tags
  const tags = data
    // filtering out the tags that...

    .map((tag, i) => {
      return (
        <Tag
          id={tag.id}
          key={i}
          info={tag}
          handleFavourite={(id) => addFavourite(id)}
        />
      );
    });

  /* ##### the component's output ##### */
  return <ul>{tags}</ul>;
};

GraphQL 代码

const client = new ApolloClient({
  uri: "https://xxxx.herokuapp.com/v1/graphql",
});

const GQLTAGS = gql`
  {
    tag(
      order_by: { tag_related_counts_aggregate: { count: desc } }
      where: { label: { _nin: ["None", "null"] } }
    ) {
      id
      label
      tag_related_counts_aggregate {
        aggregate {
          count
        }
      }
    }
  }
`;

const GQLSIMILARTAGS = gql`
  query($search_label: String!) {
    tag(
      where: { tag_related_counts: { search_label: { _eq: $search_label } } }
      distinct_on: id
    ) {
      label
      tag_related_counts(order_by: { count: desc }) {
        count
        other_label
        search_label
      }
    }
  }
`;


function GQLFunc(props) {
  const { loading, error, data } = useQuery(GQLTAGS);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :(</p>;

  let CallingApp = props.callingApp;
  if (data) return <CallingApp data={data.tag} />;
}
export { client, GQLTAGS, GQLFunc, GQLFuncSecond, GQLSIMILARTAGS };

【问题讨论】:

  • 查询tag签名?
  • tag(where.???? .. f.e.来自 graphiql 文档
  • @xadm 不幸的是,我没有你的理解水平,所以不理解这个建议。澄清。我想用从这个标签传递给ShortListdata.tag.label)的标签替换当前的硬编码字符串(在这个例子中是“云”)searchLabel={"cloud"}。因此,如果我单击“安全”标签,它当前会传递给ShortList ,但我还想通过GQLFuncSecond 函数对这个字符串运行GQLSIMILARTAGS 查询。

标签: reactjs graphql react-apollo apollo-client


【解决方案1】:

暂时忘记你所拥有的......

您应该传递与服务器中定义的查询形状匹配的变量

...这个形状怎么样?您可以在 graphiql 文档中阅读它

...如果tag 查询需要where 参数,那么您应该传递where 变量(无论它是字符串还是复杂对象 - 就像本例一样),只有一个变量...

查看“根”变量,whereorder_bydistinct_on - graphiql 文档中为tag 查询定义的所有“输入类型”。

您不仅应该用一些[随机]“更深”/“内部”变量替换一些查询/参数元素......它可以工作,但它很快变得难以管理......糟糕的 DX。

您应该使用您的search_label(在本例中为道具)准备where 对象并将where 作为变量传递。不难猜到您的查询应该是这样的:

query someNameForRelatedTagsQuery($where: where) {
  tag( where: $where ) {
    id
    label

传递给查询的变量对象:

const vars = {
  where: { 
    tag_related_counts: { 
      search_label: { 
        _eq: props.search_label
} } } };

useQuery 之前定义,在useQuery 选项中使用{ variables: vars }(第二个参数)...变量对象也可以在惰性查询调用中使用。

它与早期的“工作”硬编码查询有何关系? - 相同的结构,其他地方。

【讨论】:

  • 感谢您的回答。由于我的GQLSIMILARTAGS 中已经有tag(wheresearch_label 的变量(在GrpahIQL 中使用变量的查询),我不明白如何使用提供的信息来帮助解决问题。
  • 再读一遍,你必须忘记这一点——再一次,忘记......这是误导
  • 你能告诉我如何与我的代码集成吗?我不知道从哪里开始。
  • 您必须学习如何传递变量,这里对此进行了解释。如果您仍然不知道,那么从更简单的示例/文档/教程开始......之后您应该能够在您的代码中使用它。使用此提示,此用例相关。只是不要坚持你硬编码的内容。
  • 也许(可能)我的问题不够清楚。我终于得到了这个工作并发布了我的答案。我使用了我已经有的代码,并进行了一些小的修改。感谢您的帮助。
【解决方案2】:

我现在可以使用这种方法将字符串 (data.tag.label) 传递给 useQuery 变量。它有效,但很高兴听到任何更好的方法。

useState存储字符串标签数据

const [strfavourites, setstrFavourites] = useState([]);

标签点击ShortList时触发的功能

  const addstrFavourite = (id) => {
    const newSet = strfavourites.concat([id]);
    setstrFavourites(newSet);
  };

addstrFavourite 添加到ShortList 组件:

 handleFavourite={(id) =>
          addstrFavourite(data.find((tag) => tag.id === fav))

只有在strfavourites长度> 0时才调用useQuery函数

const hasstrFavourites = strfavourites.length > 0; 


 {hasstrFavourites &&
      strfavourites.map(function (d) {
        return <GQLFuncSecond key={d.label} searchLabel={d.label} />;
      })}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-17
    • 2016-12-03
    • 2012-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-16
    相关资源
    最近更新 更多