我已经创建了自定义的自动完成(Autosuggestions)组件。当我将字符串的硬编码数组传递给自动完成组件时,一切工作都很好,但是当我尝试从API作为道具传递数据时,第一次搜索没有任何结果。每次都在第一次之后精确显示结果
我尝试了不同的选项,但是当用户第一次搜索数据时似乎不存在,并且自动完成功能以空数组呈现。我已经测试了相同的API端点,并且每次返回时都会返回数据。
具有自动完成功能的首页组件
const filteredUsers = this.props.searchUsers.map((item) => item.firstName).filter((item) => item !== null);
const autocomplete = (
<AutoComplete
items={filteredUsers}
placeholder="Search..."
label="Search"
onTextChanged={this.searchUsers}
fieldName="Search"
formName="autocomplete"
/>
);
自动完成组件可过滤插入的数据并显示建议列表,问题可能出在onTextChange内:
export class AutoComplete extends Component {
constructor(props) {
super(props);
this.state = {
suggestions: [],
text: '',
};
}
// Matching and filtering suggestions fetched from the backend and text that user has entered
onTextChanged = (e) => {
const value = e.target.value;
let suggestions = [];
if (value.length > 0) {
this.props.onTextChanged(value);
const regex = new RegExp(`^${value}`, 'i');
suggestions = this.props.items.sort().filter((v) => regex.test(v));
}
this.setState({ suggestions, text: value });
};
// Update state each time user press suggestion
suggestionSelected = (value) => {
this.setState(() => ({
text: value,
suggestions: []
}));
};
// User pressed the enter key
onPressEnter = (e) => {
if (e.keyCode === 13) {
this.props.onPressEnter(this.state.text);
}
};
render() {
const { text } = this.state;
return (
<div style={styles.autocompleteContainerStyles}>
<Field
label={this.props.placeholder}
onKeyDown={this.onPressEnter}
onFocus={this.props.onFocus}
name={this.props.fieldName}
formValue={text}
onChange={this.onTextChanged}
component={RenderAutocompleteField}
type="text"
/>
<Suggestions
suggestions={this.state.suggestions}
suggestionSelected={this.suggestionSelected}
theme="default"
/>
</div>
);
}
}
const styles = {
autocompleteContainerStyles: {
position: 'relative',
display: 'inline',
width: '100%'
}
};
AutoComplete.propTypes = {
items: PropTypes.array.isRequired,
placeholder: PropTypes.string.isRequired,
onTextChanged: PropTypes.func.isRequired,
fieldName: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
onPressEnter: PropTypes.func.isRequired,
onFocus: PropTypes.func
};
export default reduxForm({
form: 'Autocomplete'
})(AutoComplete);
预期结果:每次用户使用textinput搜索时,他应该获得建议结果 实际结果:首次用户使用textinput搜索时,他没有获取数据。只有在有首次数据之后
答案 0 :(得分:1)
它在硬编码时有效,但在使用API时无效,因为您的过滤发生在onTextChanged
中。进行硬编码后,您的AutoComplete
具有可以在首次调用onTextChanged
(this.props.items.sort().filter(...
)时使用的值,但是使用API时,items
道具将为空,直到您使用API返回-完成此功能后。
为了处理来自API的结果,您需要在道具更改时进行过滤。 react文档实际上涵盖了非常相似的情况here(请参见第二个示例,因为第一个示例显示了getDerivedStateFromProps
的使用不必要地复杂),重要的部分是他们使用了PureComponent
来避免不必要的重新渲染,然后在渲染中进行过滤,例如在您的情况下:
render() {
// Derive your filtered suggestions from your props in render - this way when your API updates your items prop, it will re-render with the new data
const { text } = this.state;
const regex = new RegExp(`^${text}`, 'i');
suggestions = this.props.items.sort().filter((v) => regex.test(v));
...
<Suggestions
suggestions={suggestions}
...
/>
...
}