【发布时间】:2020-05-14 18:48:28
【问题描述】:
我有一个使用 Apollo 客户端的带有 GraphQL 的 React 项目。我试图弄清楚如何根据搜索文本更改查询结果。我在后端实现了查询搜索,它工作得很好。 但我不知道如何使用相同的查询在 React 中设置过滤器。 尽管有关于如何过滤 https://www.howtographql.com/react-apollo/7-filtering-searching-the-list-of-links/ 的教程,但它不使用 ES6,我真的不知道该怎么做。我卡在这个过滤器上大约 10 天。
我会告诉你我的代码。
App.js
import React from 'react';
import HeroesDota from './components/HeroesDota';
import Search from './components/HeroSearch'
import { ApolloProvider } from '@apollo/react-hooks';
import { ApolloClient } from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";
import { HttpLink } from "apollo-link-http";
const cache = new InMemoryCache();
const link = new HttpLink({
uri: "http://localhost:8000/graphql/"
});
const client = new ApolloClient({
cache,
link
});
const App = () => {
return (
<ApolloProvider client={client}>
<Search />
<HeroesDota />
</ApolloProvider>
)};
export default App;
HeroesDota.js(组件)
import React from 'react'
import gql from "graphql-tag";
import { useQuery } from '@apollo/react-hooks';
import '../index.css'
import styled from 'styled-components';
const Images = styled.img`
margin:0;
border: 3px solid #288eea;
display: inline;
width: 90px;
height: 50px;
`
const HEROES_DOTA2 = gql`
query {
heroes {
name
heroType
image
}
}
`;
const HeroesDota = () => {
const { loading, error, data } = useQuery(HEROES_DOTA2);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
return data.heroes.map(({name, heroType, image }) => (
<div className="row" key={Math.random() + 1}>
<div className="column">
<button className="button-hero"><Images className="hero_images" src= {`${image}`} alt={name}></Images></button>
<div className="hero_info">{name} - {heroType}</div>
</div>
</div>
));
}
export default HeroesDota;
HeroSearch.js(没有按我预期工作的组件)
import React, { useState } from 'react'
import gql from "graphql-tag";
import { withApollo } from 'react-apollo'
import Hero from './HeroesDota'
import '../index.css'
const SEARCH_HEROES = gql`
query ($search: String) {
heroes (search: $search) {
id
name
}
}
`;
const Search = () => {
const [heroes, setHeroes] = useState([])
const [search, setSearch] = useState('')
const _executeSearch = async () => {
const { search } = search
const result = await this.props.client.query({
query: SEARCH_HEROES,
variables: { search },
})
const heroes = result.data.heroes.name
setHeroes({ heroes })
}
return (
<div>
<div>
Search
<input
type='text'
onChange={e => setSearch({ search: e.target.value })}
/>
<button onClick={() => _executeSearch()}>OK</button>
</div>
{heroes.map((hero, index) => (
<Hero key={hero.id} hero={hero} index={index} />
))}
</div>
)
}
export default withApollo(Search)
按下 OK 按钮执行搜索后,我收到以下错误。 未处理的拒绝(ReferenceError):在初始化之前无法访问“搜索”。
如果我尝试像在 Component HeroesDota 中那样做类似的事情,我仍然无法做到。
有谁知道如何使用 es6 在 React 中过滤查询,而不是像他们在本教程中所做的那样基于类的组件。
谢谢
【问题讨论】:
-
onChange={e => setSearch(e.target.value)}为什么是const heroes = result.data.heroes.name而不是heroes? -
const { search } = search是错误原因 - 不必要的分解,根本没有必要 -
即使我改变了,我仍然得到错误,我无法在初始化之前访问搜索
-
是的,我改变了。已删除,但现在我得到了,如果我有 this.props.client -> 未处理的拒绝(TypeError):无法读取未定义的属性“道具”
-
功能组件中没有
this-useQueryuseLazyQuery` hooks
标签: django reactjs graphql apollo