如何在React中动态填充下拉列表?

时间:2019-12-16 10:45:17

标签: javascript reactjs

我有一个简单的工作代码,其中根据用户输入的值过滤下拉菜单中的选项(静态),然后允许用户从下拉列表中选择选项。

我想要实现的目标:

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}`,
    })),
  };
}

0 个答案:

没有答案