【发布时间】:2018-10-25 07:53:19
【问题描述】:
React Async Select loadoption 有时无法加载选项。这是一个非常奇怪的现象,在一组查询反应 loadoptions 没有加载任何值但我可以从日志中看到结果正确来自后端查询之后。我的代码库完全是最新的 react-select 新版本并使用
“反应选择”:“^2.1.1”
这是我的 react-async 选择组件的前端代码。我确实在我的 getOptions 函数中使用 debounce 来减少后端搜索查询的数量。我猜这不应该引起任何问题。我想补充一点,我在这种情况下观察到的另一点, loadoptions serach 指标 ( ... ) 也不会出现在这种现象中。
import React from 'react';
import AsyncSelect from 'react-select/lib/Async';
import Typography from '@material-ui/core/Typography';
import i18n from 'react-intl-universal';
const _ = require('lodash');
class SearchableSelect extends React.Component {
constructor(props) {
super(props);
this.state = {
inputValue: '',
searchApiUrl: props.searchApiUrl,
limit: props.limit,
selectedOption: this.props.defaultValue
};
this.getOptions = _.debounce(this.getOptions.bind(this), 500);
//this.getOptions = this.getOptions.bind(this);
this.handleChange = this.handleChange.bind(this);
this.noOptionsMessage = this.noOptionsMessage.bind(this);
this.handleInputChange = this.handleInputChange.bind(this);
}
handleChange(selectedOption) {
this.setState({
selectedOption: selectedOption
});
if (this.props.actionOnSelectedOption) {
// this is for update action on selectedOption
this.props.actionOnSelectedOption(selectedOption.value);
}
}
handleInputChange(inputValue) {
this.setState({ inputValue });
return inputValue;
}
async getOptions(inputValue, callback) {
console.log('in getOptions'); // never print
if (!inputValue) {
return callback([]);
}
const response = await fetch(
`${this.state.searchApiUrl}?search=${inputValue}&limit=${
this.state.limit
}`
);
const json = await response.json();
console.log('results', json.results); // never print
return callback(json.results);
}
noOptionsMessage(props) {
if (this.state.inputValue === '') {
return (
<Typography {...props.innerProps} align="center" variant="title">
{i18n.get('app.commons.label.search')}
</Typography>
);
}
return (
<Typography {...props.innerProps} align="center" variant="title">
{i18n.get('app.commons.errors.emptySearchResult')}
</Typography>
);
}
getOptionValue = option => {
return option.value || option.id;
};
getOptionLabel = option => {
return option.label || option.name;
};
render() {
const { defaultOptions, placeholder } = this.props;
return (
<AsyncSelect
cacheOptions
value={this.state.selectedOption}
noOptionsMessage={this.noOptionsMessage}
getOptionValue={this.getOptionValue}
getOptionLabel={this.getOptionLabel}
defaultOptions={defaultOptions}
loadOptions={this.getOptions}
placeholder={placeholder}
onChange={this.handleChange}
/>
);
}
}
export default SearchableSelect;
编辑以回应史蒂夫的回答
感谢史蒂夫的回答。仍然没有运气。我尝试根据您的回复点进行回复。
- 如果我不使用 optionsValue,而是使用 getOptionValue 和 getOptionLevel,那么查询结果将无法正确加载。我的意思是加载了空白选项,没有文本值。
- 是的,你是对的,是一个返回字符串的同步方法,我不需要覆盖它。这工作正常, noOptionsMessage 显示正确。感谢指出这一点。
- actionOnSelectedOption 不是noop 方法,它可能有一些责任要执行。我尝试将 SearchableSelect 用作独立组件,如果我需要一些后端操作来执行此功能,则会相应地触发它。例如,我在项目的用户配置文件中使用它,用户可以从现有条目中更新他的学校/学院信息。当用户选择一个选项时,需要执行配置文件更新责任。
- 是的,你是对的。我不需要保持 inputValue 的状态,谢谢。
- 我确实确保 defaultOptions 是一个数组。
- 我在不使用 debounce 的情况下进行了测试,仍然没有运气。我正在使用 debounce 来限制后端调用,否则我肯定不想要的每个击键都可能有后端调用。
异步选择非常适合 2/3 查询,之后它突然停止工作。我观察到一种可区分的行为,对于这些情况,搜索指示符 ( ... ) 也没有显示。
非常感谢您抽出宝贵时间。
编辑 2 以回应史蒂夫的回答
再次感谢您的回复。我对 getOptionValue 和 getOptionLabel 的看法是错误的。如果 loadOptions 得到响应,则调用这两个函数。所以我从我之前的代码 sn-p 中删除了我的 helper optionsValue 函数,并根据(也在这篇文章中)更新了我的 code-sn-p。但仍然没有运气。在某些情况下,异步选择不起作用。我尝试截取一个这样的案例。我确实在我的本地数据库名称“tamim johnson”中使用了名称,但是当我搜索他时,我没有得到任何响应,但从后端得到了正确的响应。这是这个案例的截图
我不确定这个屏幕截图有多清晰。 Tamim johnson 在我的排名中也排在第 6 位。
感谢先生抽出宝贵时间。我不知道我做错了什么或遗漏了什么。
编辑 3 以回应史蒂夫的回答
这是名为“tamim johnson”的用户搜索的预览选项卡响应。
【问题讨论】:
-
noopdefaultProp 是这样的,如果它们不包含actionOnSelectedOption属性,您可以直接调用它(无条件)。如果 getOptionValue 和 getOptionLabel 没有像我写的那样为您工作,那么您的选项数组中的某些内容不正确。你能发布一个响应的例子吗? -
@Steve-Cutter-Blades 您好先生,我编辑我的问题以供您回复。非常感谢您的宝贵时间。
-
您需要发布响应示例。您在 DevTools 中截取了响应选项卡,但预览选项卡使您能够更清晰地扩展响应对象。此外,准确了解您在请求中发送的参数(即每次调用中的
inputValue,以及哪些通过,哪些不通过) -
@Steve-Cutter-Blades 谢谢您,先生,再次感谢您。我用预览标签更新了我的屏幕截图。
-
很抱歉,截图太小了,我看不到任何细节。如果您可以附上预览选项卡的屏幕截图,并给我您尝试使用的搜索参数。
标签: reactjs asynchronous react-select react-async