我有一个简单的工作代码,其中根据用户输入的值过滤下拉菜单中的选项(静态),然后允许用户从下拉列表中选择选项。
我想要实现的目标:
1)能够加载从loadOptions(input)函数返回的动态选项,其中input是用户键入的值。
2)用户从下拉菜单中选择选项后,便可以调用handleSelection函数。
import React from 'react';
import PropTypes from 'prop-types';
import { withRouter } from 'react-router';
import { searchUsers } from '../../api/users';
import './Search.module.css';
const SearchInputContainer = styled.div`
`;
const SearchInput = styled.input`
`;
const StyledDropdown = styled.ul`
`;
const StyledUser = styled.li`
`;
class UserSearch extends React.Component {
static propTypes = {
// Provided by withRouter()
router: PropTypes.object.isRequired,
}
constructor(props) {
super(props);
//1. This list should be populated dynamically from loadOptions()
this.items = ['Dorathy', 'Dara', 'Jack', 'Jill'];
this.state = {
suggestions: [],
text: '',
isSearching: false,
};
}
onTextChanged = (e) => {
const value = e.target.value;
let suggestions = [];
if (value.length > 0) {
const regex = new RegExp(`^${value}`, 'i');
suggestions = this.items.sort().filter(v => regex.test(v));
}
this.setState(() => ({ suggestions, text: value }));
}
suggestionSelected(value) {
this.setState(() => ({
text: value,
suggestions: [],
}));
}
renderSuggestions() {
const { suggestions } = this.state;
if (suggestions.length === 0) {
return null;
}
return (
<StyledDropdown>
{suggestions.map((item) => <StyledUser onClick={() => this.suggestionSelected(item)}> {item}</StyledUser>)}
</StyledDropdown>);
}
//2. Need to call this once option from dropdown is selected
handleSelection = (option) => {
this.props.router.push(`/users/edit/${option.value}`);
}
render() {
const { text } = this.state;
return (
<SearchInputContainer>
<SearchInput placeholder="Search" value={text} onChange={this.onTextChanged} type="text"
/>
{this.renderSuggestions()}
</SearchInputContainer>
);
}
}
export { UserSearch as BaseUserSearch };
export default withRouter(UserSearch);
//The argument input should be the value typed in by user
export async function loadOptions(input) {
const result = await searchUsers(input);
const users = result.data;
this.items = users;
return {
options: users.map(o => ({
value: o.id,
label: `${o.first_name} ${o.last_name}`,
})),
};
}