简体   繁体   English

在 React-Bootstrap-TypeAhead 中使用自定义输入时不显示选项

[英]Options not showing when using custom input in React-Bootstrap-TypeAhead

I am using React-Bootstrap-TypeAhead's latest version in my React project.我在我的 React 项目中使用 React-Bootstrap-TypeAhead 的最新版本。 The main goal is to display the options menu when the user types.主要目标是在用户键入时显示选项菜单。 The menu is displayed when using the default input component but once I use the render input method for customization the options menu stops showing:使用默认输入组件时会显示菜单,但一旦我使用渲染输入法进行自定义,选项菜单就会停止显示:

working example 工作示例

import React, { useState } from 'react';
import { AsyncTypeahead } from 'react-bootstrap-typeahead';

/* example-start */
const BasicExample = ({ key, label }) => {
  const [singleSelections, setSingleSelections] = useState([]);
  const [multiSelections, setMultiSelections] = useState([]);
  const [query, setQuery] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [options, setOptions] = useState([]);

  const PER_PAGE = 50;
  const SEARCH_URI = 'https://api.github.com/search/users';

  function makeAndHandleRequest(query, page = 1) {
    return fetch(`${SEARCH_URI}?q=${query}+in:login&page=${page}&per_page=50`)
      .then((resp) => resp.json())
      .then(({ items, total_count }) => {
        /* eslint-disable-line camelcase */
        const options = items.map((i) => ({
          avatar_url: i.avatar_url,
          id: i.id,
          login: i.login,
        }));
        return { options, total_count };
      })
      .catch((err) => console.log(err));
  }

  const _handleInputChange = (query) => {
    setQuery(query);
  };

  const _handlePagination = (e, shownResults) => {
    const { query } = this.state;
    const cachedQuery = this._cache[query];

    // Don't make another request if:
    // - the cached results exceed the shown results
    // - we've already fetched all possible results
    if (cachedQuery.options.length > shownResults || cachedQuery.options.length === cachedQuery.total_count) {
      return;
    }

    setIsLoading(true);

    const page = cachedQuery.page + 1;

    makeAndHandleRequest(query, page).then((resp) => {
      const options = cachedQuery.options.concat(resp.options);
      // this._cache[query] = { ...cachedQuery, options, page };
      setIsLoading(false);
      setOptions(options);
    });
  };

  const _handleSearch = (query) => {
    setIsLoading(true);
    makeAndHandleRequest(query).then((resp) => {
      setIsLoading(true);
      setOptions(resp?.options || []);
    });
  };

  return (
    <>
      <AsyncTypeahead
        {...{ query, isLoading, options }}
        id="async-pagination-example"
        labelKey="login"
        maxResults={PER_PAGE - 1}
        minLength={2}
        onInputChange={_handleInputChange}
        onPaginate={_handlePagination}
        onSearch={_handleSearch}
        renderInput={({ inputRef, referenceElementRef, ...inputProps }) => (
          <div className="form-group h-64">
            <label>Job Category</label>
            <div className="input-group">
              <input
                type="text"
                {...inputProps}
                ref={(input) => {
                  inputRef(input);
                  // referenceElementRef(input);
                }}
                className="form-control"
                placeholder=""
              />
            </div>
          </div>
        )}
        paginate
        placeholder="Search for a Github user..."
        renderMenuItemChildren={(option) => (
          <div key={option.id}>
            <img
              alt={option.login}
              src={option.avatar_url}
              style={{
                height: '24px',
                marginRight: '10px',
                width: '24px',
              }}
            />
            <span>{option.login}</span>
          </div>
        )}
        useCache={false}
      />
    </>
  );
};
/* example-end */

export default BasicExample;

The reason you're not seeing any results rendered is that _handleInputChange is triggering a re-render and resetting the debounced onSearch handler before it can fire.您没有看到任何呈现结果的原因是_handleInputChange正在触发重新呈现并在触发之前重置去抖动的onSearch处理程序。

You can wrap _handleSearch with useCallback to fix that:你可以用useCallback _handleSearch解决这个问题:

const _handleSearch = useCallback((query) => {
  setIsLoading(true);
  makeAndHandleRequest(query).then((resp) => {
    setIsLoading(false);
    setOptions(resp?.options || []);
  });
}, []);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM