score:4

Accepted answer
import React from "react";
import TextField from "@material-ui/core/TextField";
import Autocomplete from "@material-ui/lab/Autocomplete";
import throttle from "lodash/throttle";
import getAddress from "./api/getAddress";
import { Controller } from "react-hook-form";

const AddressInput = ({ control, name, ...rest }) => {
  const [value, setValue] = React.useState(null);
  const [inputValue, setInputValue] = React.useState("");
  const [options, setOptions] = React.useState([]);
  const fetch = React.useMemo(
    () =>
      throttle((request) => {
        const getData = getAddress(request?.input);
        getData.then((res) => {
          setOptions(JSON.parse(res)?.candidates);
          return JSON.parse(res).candidates;
        });
      }, 200),
    []
  );

  React.useEffect(() => {
    let active = true;
    if (inputValue === "") {
      setOptions(value ? [value] : []);
      return undefined;
    }

    fetch({ input: inputValue }, (results) => {
      if (active) {
        let newOptions = [];
        if (value) {
          newOptions = [value];
        }
        if (results) {
          newOptions = [...newOptions, ...results];
        }
        setOptions(newOptions);
      }
    });

    return () => {
      active = false;
    };
  }, [value, inputValue, fetch]);

  return (
    <Controller
      name={name}
      control={control}
      render={({ field }) => (
        <Autocomplete
          {...field}
          id="address"
          getOptionLabel={(option) =>
            typeof option === "string" ? option : option.address
          }
          // Add this prop to help with identifying the selected option
          getOptionSelected={(optionA, optionB) =>
            optionA.address === optionB.address
          }
          filterOptions={(x) => x}
          options={options}
          autoComplete
          includeInputInList
          filterSelectedOptions
          value={value}
          onChange={(event, newValue) => {
            console.log('newValue', newValue);
            setOptions(newValue ? [newValue, ...options] : options);
            setValue(newValue);

            // Actually change the state of react-hook-forms
            field.onChange(newValue);
          }}
          onInputChange={(event, newInputValue) => {
            setInputValue(newInputValue);
          }}
          renderInput={(params) => (
            <TextField {...rest} {...params} variant="outlined" fullWidth />
          )}
          renderOption={(option) => <span>{option.address}</span>}
        />
      )}
    />
  );
};

export default AddressInput;

Related Query

More Query from same tag