简体   繁体   中英

Load Material UI AutoComplete suggestions after user input

I have an Autocomplete component that is required to load a massive data list (up to 6000 elements) and show suggestions accordingly to the user's input.

As the data options have so many elements, whenever the user starts typing in a slow computer, it slows down and requires some time to load everything. I have to prevent it, so I came with an idea to show the user suggestions after they typed the third character. It's even giving me this error whenever the user clicks on the input box:

Warning: React instrumentation encountered an error: RangeError: Maximum call stack size exceeded console.

I need to show the suggestions after the third character input. I have tried to use the getOptionDisabled suggestion and the limitTags, but they did not work.

Here is the code:

const NameSelect = (props) => {
  return (
    <Dialog>
        <React.Fragment>
          <DialogTitle id="search-name-dialog-title">
            Search name
          </DialogTitle>
          <DialogContent>
                <Autocomplete
                  id="combo-box-client-select"
                  options={props.NameList}
                  value={props.preSelectedName}
                  
                  getOptionLabel={(option) =>
                    option.Name_name +
                    ", " +
                    option.country +
                    ", " +
                    option.city
                  }
                  onChange={(object, value) => {
                    props.preSelectedNameSet(value);
                  }}
                  renderInput={(params) => (
                    <TextField
                      {...params}
                      label="Search name"
                      variant="outlined"
                      fullWidth
                    />
                  )}
                />
              .
              .
              .
    </Dialog>
  );
};

Can someone please help me with that approach, or suggest a better one? Thanks!

Try something like this:

<Autocomplete
    inputValue={inputValue}
    onInputChange={(e) => setinputValue(event.target.value)}
    id="combo-box-demo"
    options={values}
    getOptionLabel={(option) => option}
    style={{ width: 300 }}
    renderInput={(params) => (
      <TextField {...params} label="Combo box" variant="outlined" />
    )}
    open={inputValue.length > 2}
  />

Use InputValue prop to trigger the auto complete drop down. Example: auto complete dropdown

My idea is to add a state for Autocomplete current value to watch for its autoComplete property. That state will look something like this:

  const [currentValue, useCurrentValue] = useState(props.preSelectedName);

so that your component will look something like this:

<Autocomplete
autoComplete={currentValue.length >= 3 ? true : false}
onChange={useCurrentValue}
   ...your other properties     
                />

Another idea: you might wanna use setTimeout in your onChange method to slow down the re-render. But don't forget to clearTimeout before you set them.

The feature that you require is known as "Debouncing" and it is used whenever time consuming tasks occur frequently. In your case it, everytime you type the key, the suggestions are computed and this will definetely lead to lagging.

Lodash's debounce function will implement this for you.

As far as my knowledge, I am not sure whether you can implement this with MUI Autocomplete, but a custom solution you can do something like this:-

import React, { useState, useCallback } from "react"; 
import { _ } from "lodash";


function AutoComplete() {  
 const [input, setInput] = useState("");   
 const [suggestions, setSuggestions] = useState([]);

  const updateInput = (input) => {
    setInput(input);
    /*_.debounce will fire the setSuggestions
     and fetchSuggestions only after a gap of 3000ms */
    _.debounce((input) => setSuggestions(fetchSuggestions(input), 3000));   
  };

  return (
    <div>
      <input
        value={input}
        class="input"
        onChange={(event) => updateInput(event.target.value)}
      />
      <div class="suggestions">
        <ul>
          {suggestions?.length > 0 &&
            suggestions?.map((val, idx) => (
              <li class="suggestion" key={idx}>
                {val}
              </li>
            ))}
        </ul>
      </div>
    </div>   
  ); 
}
  


export default AutoComplete;

You can style the components using the appropriate styles and materialize.css so that you get a functional replica of the Autocomplete component of MUI.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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