概述
WrappedApp
最初加载时,查询被发送到GraphQL API以获取数据(标签)。
完成后,用户可以通过单击ShortList
中的标签将项目添加到WrappedApp
中的TagsList
中(请参见下面的屏幕截图)。
问题
如何在TagsList
中单击标签(即在下面的示例中单击了安全性)以触发第二个名为GQLSIMILARTAGS
的GraphQL查询,并将结果呈现在ShortList
结果上方,或至少在控制台中.log GQLSIMILARTAGS
查询的结果? GQLSIMILARTAGS
接受一个变量,该变量将是单击并添加到ShortList
的标签。
我尝试了什么?
[我尝试修改addFavourite
中的WrappedApp
函数以使用带有GQLFunc
的新GQLSIMILARTAGS
查询来调用useQuery(GQLSIMILARTAGS)
,但这可能不是最佳方法。
这是Apollo GraphQL查询代码。
graphclient.js import React from "react"; import { gql } from "apollo-boost"; import ApolloClient from "apollo-boost"; import { useQuery } from "@apollo/react-hooks"; const client = new ApolloClient({ uri: "https://job-stats.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 { 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 };
这是主要的
WrappedApp.js
应用。
import React, { Component } from "react"; /* ############################ */ /* ##### 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 Greeting = () => <h1>Test Tags</h1>; /* ##################### */ /* ##### Shortlist ##### */ /* ##################### */ const ShortList = ({ favourites, data, deleteFavourite }) => { 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, filter, favourites, addFavourite }) => { const input = filter; // Gather list of tags const tags = data // filtering out the tags that... .filter((tag, i) => { return ( // ...are already favourited favourites.indexOf(tag.id) === -1 && // ...are not matching the current search value !tag.label.indexOf(input) ); }) // ...output a <Name /> component for each name .map((tag, i) => { // only display tags that match current input string return ( <Tag id={tag.id} key={i} info={tag} handleFavourite={(id) => addFavourite(id)} /> ); }); /* ##### the component's output ##### */ return <ul>{tags}</ul>; }; /* ###################### */ /* ##### Search bar ##### */ /* ###################### */ // need a component class here // since we are using `refs` class Search extends Component { render() { const { filterVal, filterUpdate } = this.props; return ( <form> <input type="text" ref="filterInput" placeholder="Type to filter.." // binding the input value to state value={filterVal} onChange={() => { filterUpdate(this.refs.filterInput.value); }} /> </form> ); } } /* ############################## */ /* ##### Main app component ##### */ /* ############################## */ class WrappedApp extends Component { constructor(props) { super(props); this.state = { filterText: "", favourites: [], }; } // update filterText in state when user types filterUpdate(value) { this.setState({ filterText: value, }); } // add clicked name ID to the favourites array addFavourite(id) { const newSet = this.state.favourites.concat([id]); this.setState({ favourites: newSet, }); } // remove ID from the favourites array deleteFavourite(id) { const { favourites } = this.state; const newList = [...favourites.slice(0, id), ...favourites.slice(id + 1)]; this.setState({ favourites: newList, }); } render() { const hasSearch = this.state.filterText.length > 0; return ( <div> <header> <Greeting /> <Search filterVal={this.state.filterText} filterUpdate={this.filterUpdate.bind(this)} /> </header> <main> <ShortList data={this.props.data} favourites={this.state.favourites} deleteFavourite={this.deleteFavourite.bind(this)} /> <TagsList data={this.props.data} filter={this.state.filterText} favourites={this.state.favourites} addFavourite={this.addFavourite.bind(this)} /> {/* Show only if user has typed in search. To reset the input field, we pass an empty value to the filterUpdate method */} {hasSearch && ( <button onClick={this.filterUpdate.bind(this, "")}> Clear Search </button> )} </main> </div> ); } } export default WrappedApp;
这是我的
index.js
import React from "react";
import ReactDOM from "react-dom";
import * as serviceWorker from "./serviceWorker";
import { ApolloProvider } from "@apollo/react-hooks";
import { client, GQLTags, GQLFunc } from "./graphclient";
import WrappedApp from "./WrappedApp";
/* ############################ */
/* ##### Single tag ##### */
/* ############################ */
ReactDOM.render(
<ApolloProvider client={client}>
<GQLFunc callingApp={WrappedApp} />
</ApolloProvider>,
document.getElementById("root")
);
概述最初加载WrappedApp时,会将查询发送到GraphQL API以获取数据(标签)。完成此操作后,用户可以通过单击...
可以很简单