如何显示搜索结果?

时间:2021-03-20 18:54:13

标签: html reactjs react-native asynchronous search

我是 React 的新手。我正在构建一个以搜索功能开始的 Web 应用程序。我的应用程序的用户应该首先搜索一家公司,选择他们想要的公司,然后应用程序应该向他们显示我们拥有的关于该公司的一些信息:名称、域名、城市、地区(州) ,也许还有 short_description。

我有一个异步搜索,可以从我的 Firebase Firestore 集合中填充公司名称的选项,但是一旦选择了公司,我的组件就不会显示其他信息。

这是我的代码:

import React, { Component } from "react";
import AsyncSelect from "react-select/async";
import { defaultTheme } from "react-select";
import Button from "@atlaskit/button";
import firebase from "./../util/firebase";

const { colors } = defaultTheme;

const selectStyles = {
  control: (provided) => ({ ...provided, minWidth: 240, margin: 8 }),
  menu: () => ({ boxShadow: "inset 0 1px 0 rgba(0, 0, 0, 0.1)" })
};

const db = firebase.firestore();

class DashSearch extends Component {
  state = { isOpen: false, value: undefined };
  toggleOpen = () => {
    this.setState((state) => ({ isOpen: !state.isOpen }));
  };
  onSelectChange = (value) => {
    this.toggleOpen();
    this.setState({ value });
  };

  constructor(props) {
    super(props);
    this.state = {
      results: []
    };
    this.search = this.search.bind(this);
  }
  search(results) {
    this.setState({ results });
  }

  getInfo = (search) => {
    db.collection("organizations")
      .where("name", "===", search)
      .then(({ data }) => {
        this.setState({ results: data.data });
      });
  };

  loadOptions = async (search) => {
    search = search.toLowerCase().replace(/\W/g, "");
    return new Promise((resolve) => {
      db.collection("orgs")
        .where("keywords", "array-contains", search)
        .get()
        .then((docs) => {
          if (!docs.empty) {
            let results = [];
            docs.forEach(function (doc) {
              const company = {
                value: doc.data().uuid,
                label: doc.data().name,
                domain: doc.data().domain,
                region: doc.data().region,
                city: doc.data().city
              };
              results.push(company);
            });
            return resolve(results);
          } else {
            return resolve([]);
          }
        });
    });
  };

  handleOnChange = () => {
    this.setState(
      {
        search: this.search.value
      },
      () => {
        if (this.state.search && this.state.search.length > 1) {
          if (this.state.search.length % 2 === 0) {
            this.getInfo();
          }
        } else if (!this.state.search) {
        }
      }
    );
  };

  render() {
    const { isOpen, value } = this.state;
    return (
      <div className="mt-4 mb-40">
        <Dropdown
          isOpen={isOpen}
          onClose={this.toggleOpen}
          target={
            <Button
              iconAfter={<ChevronDown />}
              onClick={this.toggleOpen}
              isSelected={isOpen}
            >
              {value ? `Company: ${value.label}` : "Select a Company"}
            </Button>
          }
        >
          <AsyncSelect
            autoFocus
            backspaceRemovesValue={true}
            components={{ DropdownIndicator, IndicatorSeparator: null }}
            controlShouldRenderValue={true}
            hideSelectedOptions={false}
            menuIsOpen
            placeholder="Search..."
            styles={selectStyles}
            tabSelectsValue={false}
            value={this.search.value}
            isClearable
            isSearchable
            loadOptions={this.loadOptions}
            onChange={this.handleOnChange}
          />
        </Dropdown>
        <div>
          <p>{this.state.results}</p>
        </div>
      </div>
    );
  }
}

const Menu = (props) => {
  const shadow = "hsla(218, 50%, 10%, 0.1)";
  return (
    <div
      css={{
        backgroundColor: "white",
        borderRadius: 4,
        boxShadow: `0 0 0 1px ${shadow}, 0 4px 11px ${shadow}`,
        marginTop: 8,
        position: "absolute",
        zIndex: 2
      }}
      {...props}
    />
  );
};
const Blanket = (props) => (
  <div
    css={{
      bottom: 0,
      left: 0,
      top: 0,
      right: 0,
      position: "fixed",
      zIndex: 1
    }}
    {...props}
  />
);
const Dropdown = ({ children, isOpen, target, onClose }) => (
  <div css={{ position: "relative" }}>
    {target}
    {isOpen ? <Menu>{children}</Menu> : null}
    {isOpen ? <Blanket onClick={onClose} /> : null}
  </div>
);
const Svg = (p) => (
  <svg
    width="24"
    height="24"
    viewBox="0 0 24 24"
    focusable="false"
    role="presentation"
    {...p}
  />
);
const DropdownIndicator = () => (
  <div css={{ color: colors.neutral20, height: 24, width: 32 }}>
    <Svg>
      <path
        d="M16.436 15.085l3.94 4.01a1 1 0 0 1-1.425 1.402l-3.938-4.006a7.5 7.5 0 1 1 1.423-1.406zM10.5 16a5.5 5.5 0 1 0 0-11 5.5 5.5 0 0 0 0 11z"
        fill="currentColor"
        fillRule="evenodd"
      />
    </Svg>
  </div>
);
const ChevronDown = () => (
  <Svg style={{ marginRight: -6 }}>
    <path
      d="M8.292 10.293a1.009 1.009 0 0 0 0 1.419l2.939 2.965c.218.215.5.322.779.322s.556-.107.769-.322l2.93-2.955a1.01 1.01 0 0 0 0-1.419.987.987 0 0 0-1.406 0l-2.298 2.317-2.307-2.327a.99.99 0 0 0-1.406 0z"
      fill="currentColor"
      fillRule="evenodd"
    />
  </Svg>
);

export default DashSearch;

这就是它的样子:

enter image description here

0 个答案:

没有答案