mattsmith5
mattsmith5

Reputation: 1073

React Material UI Autocomplete, prevent OnInputChange, after selecting value from dropdown

How do I prevent React Material UI to not trigger onInputChange, when a person selects a option from the dropdown? After using the dropdown, it retriggers the API again, which I am trying to prevent .

    <Autocomplete
      options={patientOptions}
      onChange={(_event, newValue) => {
        onPatientChange(newValue);
      }}
      noOptionsText={
        <Typography>
          <Box color="text.hint">
            {patientLength === 0
              ? 'Type at least 1 character to search'
              : 'No results found.'}
          </Box>
        </Typography>
      }
      onInputChange={async (
        event: object,
        value: string,
        reason: string,
      ) => {
        setPatientLength(value.length);
        if (value.length > 0) {
          await getPatient(value, undefined).then(x => {
            setPatientOptions(x.patients);
          });
        }
      }}
      getOptionLabel={option => getPatientLabel(option)}
      renderInput={params => (
        <TextField
          value={patientValue}
          {...params}
        />
      )}
    />

Upvotes: 4

Views: 4157

Answers (1)

morganney
morganney

Reputation: 13560

To prevent making API calls when a user selects an option from the dropdown, you can consult the reason argument to onInputChange. The reason will always be reset when a user selects an option and input when a user enters custom text. In the latter case you should also check whether the custom text is included in the patientOptions.

I've added the following conditions to to your conditional logic inside onInputChange: reason === 'input' && !patientOptions.find(value).

    <Autocomplete
      options={patientOptions}
      onChange={(_event, newValue) => {
        onPatientChange(newValue);
      }}
      noOptionsText={
        <Typography>
          <Box color="text.hint">
            {patientLength === 0
              ? 'Type at least 1 character to search'
              : 'No results found.'}
          </Box>
        </Typography>
      }
      onInputChange={async (
        event: object,
        value: string,
        reason: string,
      ) => {
        setPatientLength(value.length);
        if (value.length > 0 && reason === 'input' && !patientOptions.find(value)) {
          await getPatient(value, undefined).then(x => {
            setPatientOptions(x.patients);
          });
        }
      }}
      getOptionLabel={option => getPatientLabel(option)}
      renderInput={params => (
        <TextField
          value={patientValue}
          {...params}
        />
      )}
    />

Upvotes: 7

Related Questions