我正尝试根据2个从GraphQL提取数据的查询,使用自动完成组件来建议数据。
const handleSearchChange = (evt, newInputValue) => {
const {
agentsEmail,
prefix,
appsName,
role,
fromDate,
toDate,
} = this.props;
console.log("handle Search Change")
this.setState({ userInput: evt.target.value });
if (newInputValue.length > 0) {
this.setState({ open: true });
setTimeout(() => { this.prepareFilterData(appsName, agentsEmail, prefix, role, fromDate, toDate); }, 500);
} else {
this.setState({ open: false });
}
}
const handleSelection = (evt, evtSelection, reason) => {
console.log(reason, "REASON handle Selection")
this.setState({ selection: evtSelection });
/* map over selection and for each element push to listings the element.id
to build the list of ids to be used by the seearch button handle event */
this.state.selection.map( (selection) => listings.push(selection.id))
console.log(this.state.selection, "SELECTION")
}
<Autocomplete
id="listings-filter"
multiple
open={this.state.open}
onOpen={handleOpen}
onClose={() => this.setState({ open: false })}
options={filterList}
limitTags={4}
groupBy={(option) => option.key}
disableCloseOnSelect
onChange={handleSelection}
onInputChange={handleSearchChange}
getOptionLabel={(option) => option.value}
renderOption={(option, { selected }) => (
<React.Fragment>
<Checkbox
icon={icon}
checkedIcon={checkedIcon}
style={{ marginRight: 8 }}
checked={selected}
/>
{option.value}
</React.Fragment>
)}
renderInput={(params) => (
<TextField {...params} label="Search listings by" placeholder="Address, MLS" />
)}
/>
我正在使用类组件,并且选项是我格式化的列表,以使它们可以与“自动完成”组件进行分组,但始终使用选项的先前状态。例如:
我在输入上键入 ca ,它会获取100个值,但是当我模糊输入时会使用100个值,从而清除输入并加载100个字段。然后当我键入其他内容时,空选项被加载。我总是需要执行+1 change事件来获取实际的选项列表,我尝试设置为false的 clearOnBlur 属性无法解决问题,因为由于模糊输入时不会触发change事件它永远不会更新状态(+1)。
知道是什么原因造成的吗?谢谢建议
这是我的问题的动画示例:
编辑:删除选定的选项或选择它们时,也会发生此行为,如果我选择一个选项,则change事件反映一个空列表,当我选择第二个选项时,它仅反映我选择的第一个。
这是我用来格式化和更新 filterList 的函数,我使用fetchMls和fetchAddresses来获取数据,然后使用 mergeFilterData 更新在选项属性
prepareFilterData = async (appsName, agentsEmail, prefix, role, fromDate, toDate) => {
await this.fetchMls(appsName, agentsEmail, prefix, role, fromDate, toDate);
await this.fetchAddresses(appsName, agentsEmail, prefix, role, fromDate, toDate);
this.setState({
filterList: mergeFilterData(this.state.fetchedAddresses, this.state.fetchedMls, [])
});
console.log(this.state.filterList, "FINAL DATA")
/* this.setState({
filteredList: handleListChange(userInput, listingsList, 0.5),
}); */
}
EDIT2:这是在提取数据时将其格式化并保存在要使用的状态下的,我用来提取数据的功能之一。
fetchMls = async (appsName, agentsEmail, prefix, role, fromDate, toDate) => {
const enumerationAppName = appsName.map((appName) => appName.enumeration);
const listAgents = agentsEmail.map((agent) => agent.name || agent);
console.log(this.state.userInput, "USER INPUT ON FETCH MLS")
const query = {
query: GET_LISTINGS_BY_MLS_PREFIX_QUERY,
variables: {
appsName: enumerationAppName,
agentsEmail: listAgents,
prefix,
fromDate: formatDate(fromDate),
toDate: formatDate(toDate),
mlsPrefix: this.state.userInput || "1",
},
};
applicationClient
.query(query)
.then((response) => {
if (response) {
if (!isEmpty(response.data.getListingsByMlsPrefix.data)) {
const result = response.data.getListingsByMlsPrefix.data.map(
(listing) => listing
);
const formatedMls = formatMls(result);
this.setState({ fetchedMls: formatedMls });
}
}
})
.catch((err) => {
this.setState({ fetchedMls: [] });
});
};
答案 0 :(得分:0)
如果您需要在状态更新后处理数据,最好的方法是使用回调函数:
const handleSearchChange = (evt, newInputValue) => {
const {
agentsEmail,
prefix,
appsName,
role,
fromDate,
toDate,
} = this.props;
console.log("handle Search Change")
this.setState({
userInput: newInputValue,
open: newInputValue > 0
});
if (newInputValue.length > 0) {
setTimeout(() => { this.prepareFilterData(appsName, agentsEmail, prefix, role, fromDate, toDate); }, 500);
}
}
const handleSelection = (evt, evtSelection, reason) => {
console.log(reason, "REASON handle Selection")
this.setState({ selection: evtSelection }, ()=> {
this.state.selection.map( (selection) => listings.push(selection.id))
console.log(this.state.selection, "SELECTION")
});
/* map over selection and for each element push to listings the element.id
to build the list of ids to be used by the seearch button handle event */
}
我不知道this.fetchMls和this.fetchAddresses函数是什么,但我建议您直接获取数据,如下所示:
prepareFilterData = async (appsName, agentsEmail, prefix, role, fromDate, toDate) => {
const fetchedAddresses = await this.fetchMls(appsName, agentsEmail, prefix, role, fromDate, toDate);
const fetchedMls = await this.fetchAddresses(appsName, agentsEmail, prefix, role, fromDate, toDate);
this.setState({
filterList: mergeFilterData(fetchedAddresses, fetchedMls, [])
}, ()=> console.log(this.state.filterList, "FINAL DATA"));
}
希望对您有所帮助;)
答案 1 :(得分:0)
问题与实质性的UI组件无关,问题与我正在获取的数据有关,因为我正在获取3个不同的查询,而我都遇到了竞争条件错误,因此我通过使用Promises.all()如果对任何人都有用;)