在类组件的方法中获取查询 [英] Fetching query in method of a class component

查看:68
本文介绍了在类组件的方法中获取查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Apollo客户端(2.6.3)与react.是否可以在类组件的方法中获取数据?我正在构建一个全局搜索组件,并且仅在键入第3个(及其后的每个)字符时才想获取数据.现在,它已通过访存api实现,但我想切换到apollo客户端和graphql api.

Apollo client (2.6.3) with react. Is it possible to fetch data in a method of a class component? I'm building a global search component and I want to fetch data only when 3rd (and each subsequent) character is typed. Right now it is implemented with fetch api but I want to switch to apollo client and graphql api.

直到这一刻,我还没有遇到阿波罗客户端API的任何问题,因为我使用了< Query/> 组件.

Until this moment I haven't gotten any problems with apollo client API cause I use <Query/> component.

我尝试使用新的hooks api,但事实证明useLazyQuery()只能在功能组件(挂钩规则)中使用.

I've tried to use new hooks api but it turned out that useLazyQuery() can be used only in a function component (rules of hooks).

这是我到目前为止所做的.我知道该组件很乱,我很乐意提出建议.这是我的第一个React应用.

This is what I have done so far. I know that component is messy and I'm open to suggestions. This is my first react app.

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;

推荐答案

Apollo Client提供了一个基于Promise的API,该API对查询/变异的运行时间/位置提供了更重要的控制.这是他们的文档中的示例:

Apollo Client offers a Promise-based API that provides more imperative control over when/where your queries/mutations are run. Here's an example from their docs:

client
  .query({
    query: gql`
      query GetLaunch {
        launch(id: 56) {
          id
          mission {
            name
          }
        }
      }
    `,
    variables: { ... }
  })
  .then(result => console.log(result));

您可以导入客户端并以任何方法或功能(例如使用Promises进行的任何其他异步操作)使用此模式.

You can import your client and use this pattern in any method or function like any other async operation using Promises.

这篇关于在类组件的方法中获取查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆