概述
应用最初会查询GraphQL API,并使用TagsList
呈现“标记”(字符串)。
然后用户可以单击一个标签,然后将该标签传递到ShortList
并进行渲染。
我要做什么?
我有另一个名为GQLSIMILARTAGS
的GraphQL查询,它接受一个字符串变量,并在useQuery
中使用GQLFuncSecond
进行调用。我想在用户点击其中一个标签时触发此操作。
我知道查询可以像下面这样用硬编码的searchLabel
作为变量来传递。
<GQLFuncSecond searchLabel={"cloud"} />
问题
当用户从data.tag.label
单击标签时,如何将字符串(useQuery
传递到此TagsList
变量中。
我不知道如何将用户选择的标签(添加到ShortList
时)传递到我的GQLFuncSecond
函数中。
例如,我应该在GQLFuncSecond
中呼叫ShortList
吗?我该怎么办?
主应用
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 };
答案 0 :(得分:1)
您应传递与服务器中定义的查询形状匹配的变量
...这种形状看起来如何?您可以在graphiql文档中阅读它
...如果tag
查询期望使用where
参数,那么您应该传递where
变量(无论是字符串还是复杂对象-在这种情况下),只有一个变量...
看看“根”变量where
,order_by
,distinct_on
-在graphiql文档中为tag
查询定义的所有“输入类型”。
您不仅应该用一些[随机]'deeper'/'internal'变量替换某些查询/参数元素,它可以工作,但很快就可以处理,糟糕的DX。
您应该使用where
(在这种情况下为prop)准备search_label
对象,并将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 }
(第二个参数)中使用...变量对象也可以在惰性查询调用中使用。
它与早期的“工作”硬编码查询有何关系? -相同的结构,其他位置。
答案 1 :(得分:0)
我现在可以使用这种方法将字符串(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))
如果useQuery
长度> 0,则仅调用strfavourites
函数
const hasstrFavourites = strfavourites.length > 0;
{hasstrFavourites &&
strfavourites.map(function (d) {
return <GQLFuncSecond key={d.label} searchLabel={d.label} />;
})}