首页 > 解决方案 > 自动建议/组合框建议不会显示

问题描述

由于某种原因,建议不会显示,控制台中没有错误消息。

组合框流

塞纳里奥

  1. 用户点击组合框,显示建议。(在职的)

  2. 用户选择一个建议。建议显示在组合框中。(在单个跨度中选择其加载)

  3. 如果用户在选择后单击组合框,组合框将清除值,但之前的选择将显示为突出显示的首选。还更新了首选下方的建议显示。(我真的需要这方面的帮助,我可以在控制台日志中看到数据。但由于没有显示建议,我可以判断它是否按要求显示)

(参见图片以供参考)

反应自动建议反应自动建议@9.3.4

组件代码

import React, { Component } from "react";
import ReactDOM, { findDOMNode } from "react-dom";
import PropTypes from "prop-types";
import classNames from "classnames";
import Autosuggest from "react-autosuggest";

import Icon from '../Components/Icons/Icons';

class Autocomplete extends Component {
  constructor() {
    super();

    this.state = {
      value: "",
      suggestions: [],
      isTouched: false,
      multi: false,
      selectedInput: ""
    };

    this.onChange = this.onChange.bind(this);
    this.onClick = this.onClick.bind(this);
    this.blurCallback = this.blurCallback.bind(this);
    this.triggerFocus = this.triggerFocus.bind(this);
    this.handleClear = this.handleClear.bind(this);
  }

  getSuggestionValue = suggestion => suggestion.text;

  renderSuggestion = suggestion => (<span>{suggestion.text}</span>)

  escapeRegexCharacters = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");

  getSectionSuggestions = section => section && section.items;

  getSuggestions = (value, selected, reason) => {
    let suggestions = this.props.data;

    if (value !== undefined) {
      const escapedValue = this.escapeRegexCharacters(value.trim());
      const selectedInput = [];
      selectedInput.push(selected);
      const regex = new RegExp(escapedValue, "i");
      const filtered = suggestions.filter(language =>
        regex.test(language.text)
      );

      if (escapedValue === "") {
        return {
          suggestions: [
            { text: selectedInput[0], items: [] },
            { text: "", items: filtered }
          ],
          multi: true
        };
      }

      if (!filtered.length) {
        return {
          suggestions: selectedInput.length > 0 ? selectedInput : filtered,
          multi: false
        };
      }

      return {
        suggestions: [{
            text: selectedInput[0],
            items: selectedInput.length > 0 ? selectedInput : filtered
          },
          {
            text: "",
            items: reason === "focused" ? suggestions : filtered
          }],
        multi: true
      };
    } else return;
  };

  onSuggestionsFetchRequested = ({ value, reason }) => {
    if (reason === "input-focused") {
      this.setState({ value: "" });
      const { multi, suggestions } = this.getSuggestions(
        value,
        this.state.selectedInput ? this.state.selectedInput : "",
        "focused"
      );
      this.setState({
        suggestions,
        multi
      });
    } else {
      const { multi, suggestions } = this.getSuggestions(
        value,
        this.state.selectedInput ? this.state.selectedInput : "",
        "notfocused"
      );
      this.setState({
        suggestions,
        multi
      });
    }
  };

  onSuggestionsClearRequested = () => {
    this.setState({
      suggestions: [],
      multi: false
    });
  };

  onChange = (event, { newValue, method }) => {
    if (method === "enter") {
      this.setState({
        value: this.state.value
      });
    } else {
      this.setState({
        value: newValue
      });
    }

    if(this.props.search) {
      this.props.search(newValue, ReactDOM.findDOMNode(this).parentNode.parentNode.querySelectorAll('li'));
    };
  };

  onSuggestionSelected = (ev,
    { suggestion, suggestionValue, suggestionIndex, sectionIndex, method }
  ) => {
    this.setState({
      selectedInput: suggestionValue
    });
  };

  blurCallback (ev) {
    this.setState({  isTouched: false });
  }

  handleClear() {
    this.setState({
      value: ''
    })
  }
  onClick(ev) {
    this.setState({ isTouched: true });
  }

  triggerFocus() {
    const input = document.getElementById(this.props.id);
    input.focus();
  }

  render() {

    const theme = {
      container: "el-form",
      containerOpen: "react-autosuggest__container--open",
      input: "autocomplete form-control",
      inputOpen: "react-autosuggest__input--open",
      inputFocused: "react-autosuggest__input--focused",
      suggestionsContainer: "react-autosuggest__suggestions-container",
      suggestionsContainerOpen:
        "react-autosuggest__suggestions-container--open",
      suggestionsList: "autocomplete-wrap",
      suggestion: "react-autosuggest__suggestion",
      suggestionFirst: "react-autosuggest__suggestion--first",
      suggestionHighlighted: "react-autosuggest__suggestion--highlighted",
      sectionContainer: "react-autosuggest__section-container",
      sectionContainerFirst: "react-autosuggest__section-container--first",
      sectionTitle: "react-autosuggest__section-title"
    };

    const {
      className,
      placeholder,
      data,
      disabled,
      label,
      labelClass,
      icon,
      iconSize,
      iconClass,
      clear,
      clearClass,
      id,
      search,
      ...attributes
    } = this.props;

    const labelClassFix = classNames(
      isNotEmpty && "active",
      disabled && "disabled",
      labelClass
    );
    const iconClassFix = classNames(
      "prefix",
      this.state.isTouched && "active",
      iconClass
    );
    const clearClassFix = classNames(
      clearClass
    )

    const isclearVisible = () => {
      let hiddenOrNot = "hidden"
      if (this.state.value) {
        hiddenOrNot = "visible";
      }
      return hiddenOrNot;
    }
    const clearStyleFix = {
      position: "absolute",
      zIndex: 2,
      top: "2.5rem",
      right: "10px",
      border: "none",
      background: "0 0",
      visibility: isclearVisible(),
    }

    let isNotEmpty =
      Boolean(this.state.value) || placeholder || this.state.isTouched;

    const { value, suggestions, multi } = this.state;

    const inputProps = {
      placeholder: placeholder,
      value,
      onChange: this.onChange,
      onBlur: this.blurCallback,
      onClick: this.onClick,
      onFocus: this.onFocus,
      id: this.props.id,
      name: this.props.name
    };

    const renderInputComponent = inputProps => (
      <div>
        { icon && <Icon icon={icon} className={iconClassFix}/> }
        <input
          type="text"
          id={id}
          name={name}
          className="form-control"
          {...inputProps}
          onFocus={(ev, val) => {
            this.onClick();
            inputProps.onFocus(ev, val);
          }}
        />
        <label
          htmlFor={id}
          id={`label for ${id}`}
          onClick={this.triggerFocus}
          className={labelClassFix}
        >
          { label }
        </label>
        { clear &&
          <Icon icon="close" onClick={this.handleClear} style={clearStyleFix}
          className={clearClassFix}/>
        }
      </div>
    );

    return (
        <Autosuggest
          multiSection={multi}
          renderSectionTitle={this.renderSuggestion}
          getSectionSuggestions={this.getSectionSuggestions}
          suggestions={suggestions}
          highlightFirstSuggestion={true}
          focusInputOnSuggestionClick={false}
          onSuggestionsClearRequested={this.onSuggestionsClearRequested}
          onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
          getSuggestionValue={this.getSuggestionValue}
          renderSuggestion={this.renderSuggestion}
          inputProps={inputProps}
          theme={theme}
          renderInputComponent={renderInputComponent}
          shouldRenderSuggestions={ () => true }
          onSuggestionSelected={this.onSuggestionSelected}
        />
    );
  }
}

Autocomplete.propTypes = {
  className: PropTypes.string,
  icon: PropTypes.string,
  id: PropTypes.string,
  name: PropTypes.string,
};

Autocomplete.defaultProps = {
  id: 'autocomplete-1',
  name: '',
  clear: true
};

export default Autocomplete;

在用组件

const states = [ "Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", "Illnois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming" ];

<Autocomplete
  data={states}
  label="Choose your state"
  icon="lightbulb"
  clear
  clearClass="grey-text" id="combobox-states" name="state-selection"
  className="mx-auto"
/>

代码沙盒

标签: reactjscomponentsautosuggest

解决方案


你需要return在你的一些回调中:

  getSuggestionValue = suggestion => {
    return suggestion;
  }

  getSectionSuggestions = (section) => {
    return section && section.items;
  }

编辑

getSuggestions你需要直接返回一个数组,而不是一个对象。见https://codesandbox.io/s/w04jpzjr4k


推荐阅读