我是 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;
这就是它的样子: