在类组件的方法中获取查询
Posted
技术标签:
【中文标题】在类组件的方法中获取查询【英文标题】:Fetching query in method of a class component 【发布时间】:2020-01-12 10:43:26 【问题描述】:带有反应的 Apollo 客户端 (2.6.3)。 是否可以在类组件的方法中获取数据? 我正在构建一个全局搜索组件,并且我只想在输入第三个(以及每个后续)字符时获取数据。现在它是用 fetch api 实现的,但我想切换到 apollo 客户端和 graphql api。
到目前为止,由于我使用的是 apollo 客户端 API,因此我还没有遇到任何问题
<Query/>
组件。
我尝试使用新的 hooks api,但结果发现 useLazyQuery() 只能在函数组件中使用(钩子规则)。
这是我到目前为止所做的。我知道那个组件很乱,我愿意接受建议。这是我的第一个 react 应用。
import React, Component from "react";
import PropTypes from "prop-types";
import Select, Icon, Button from "antd";
import es from "../../../utils/queries";
import useLazyQuery from "@apollo/react-hooks";
const Option, OptGroup = Select;
class GlobalSearch extends Component
constructor(props)
super(props);
this.searchInput = React.createRef();
state =
data: [],
value: undefined,
display: false
;
componentDidMount()
document.addEventListener("click", this.onClickOutside);
generateOptions(data)
return data.map(d =>
if (d._index === "cases")
d.label = (
<div>
<Icon style= fontSize: "18px" type="tool" />
<span style= color: "#183247" >
d._source.number + d._source.serialNumber
</span>
</div>
);
else if (d._index === "items")
d.label = (
<div>
<Icon style= fontSize: "18px" type="barcode-o" />
<span style= color: "#183247" >d._source.name</span>
</div>
);
else if (d._index === "people")
d.label = (
<div>
<Icon
type="user"
style= fontSize: "18px", float: "left", marginTop: "3px"
/>
<div style= marginLeft: "26px" >
<span style= color: "#183247" >
" "
<div>d._source.name + " " + d._source.surname</div>
</span>
<div>d._source.email</div>
</div>
</div>
);
else if (d._index === "counterparties")
d.label = (
<div>
<Icon style= fontSize: "18px" type="shop" />
<span style= color: "#183247" >d._source.name</span>
</div>
);
else
d.label = "undefined";
return d;
);
//group data according to type of the search result (index e.g. cases, items, contacts)
setData = es_data =>
const data = ;
const map = new Map();
for (const item of es_data)
if (!map.has(item._index))
map.set(item._index);
data[item._index] = [];
data[item._index].push(item);
this.setState( data: data );
;
handleSearch = value =>
if (value.length > 2)
//tutaj wyszukujemy dane na serwerze a wyniki callbackiem przesyłamy do state.data[]
//response.json() calls mixin methods from body
const host = window.location.hostname
// const loading, data = useLazyQuery(es(value));
// if (loading) return undefined;
// if (data)
// this.setData(this.generateOptions(data));
//
fetch(`http://$host:3000/api/es?searchString=$value`)
.then(response => response.json())
.then(es_data =>
this.setData(this.generateOptions(es_data));
);
;
handleChange = value =>
//przy kazdym wpisanym znaku aktualizuj wartosc pola
this.setState( value );
;
handleSelect = (key, option) =>
console.log(key);
console.log(option);
;
handleBlur = e =>
this.setState( display: false, value: undefined, data: [] );
;
onClick = () =>
this.setState( display: !this.state.display );
;
getSearchField(options)
if (this.state.display)
return (
<Select
id="global-search-field"
optionLabelProp="label"
showSearch
value=this.state.value
placeholder="search..."
style= display: this.state.display, width: "350px"
defaultActiveFirstOption=true
showArrow=false
filterOption=false
onSearch=this.handleSearch
onChange=this.handleChange
onSelect=this.handleSelect
notFoundContent="nothing here..."
onBlur=this.handleBlur
autoFocus=true
showAction=["focus"]
dropdownClassName="global-search-dropdown"
>
options
</Select>
);
render()
//generate options for each group (index)
const options = Object.keys(this.state.data).map(d => (
<OptGroup label=d>
this.state.data[d].map(d => (
<Option
className=d._index
type=d._index
key=d._id
label=d.label
>
<div>d.label</div>
</Option>
))
</OptGroup>
));
return (
<span>
this.getSearchField(options)
<Button
id="global-search"
shape="circle"
icon="search"
onClick=this.onClick
/>
</span>
);
export default GlobalSearch;
【问题讨论】:
【参考方案1】:Apollo Client 提供了一个基于 Promise 的 API,它提供了对运行查询/突变的时间/地点的更多命令式控制。以下是来自their docs 的示例:
client
.query(
query: gql`
query GetLaunch
launch(id: 56)
id
mission
name
`,
variables: ...
)
.then(result => console.log(result));
您可以导入您的客户端并在任何方法或函数中使用此模式,就像使用 Promises 的任何其他异步操作一样。
【讨论】:
您知道如何获取 400 错误请求返回的错误的 json 响应吗?以上是关于在类组件的方法中获取查询的主要内容,如果未能解决你的问题,请参考以下文章
如何在类组件中使用 next.js 中的“useRouter()”?