Material-ui: [Autocomplete] Prevent onInputChange when onChange is fired

Created on 11 Dec 2019  路  7Comments  路  Source: mui-org/material-ui

I'm not really sure whether to classify this as a bug or feature request as I'm not familiar with what's actually intended here.

When onChange is fired, onInputChange is also fired, even though the user is not actually typing into the search box. Technically, the text input _is_ changing though, so it makes sense from that standpoint that this would happen.

  • [x] I have searched the issues of this repository and believe that this is not a duplicate.

Summary 馃挕

I would argue the onInputChange event should not fire when a user selects an option, and instead only fires when they type into the input field themselves.

Motivation 馃敠

This is preventing me from tying an external API request to the user typing in the text field for search, as once the user selects an option, an extra API request is made with the full selection label. I don't want to make an extra request on user selection, as the options available to the user should remain the same.

I have also tried storing the selected option in state and checking that the selected option and the input don't match before making my API request. However, both onChange and onInputChange are executed before the state actually updates in React, so my check is always one state behind.

Autocomplete enhancement

All 7 comments

@Tybot204 We have a related issue in #18656 where we plan to switch the call order between onChange and onInputChange. However, your case is different from this related issue, it's about data fetching and not form validation.

In the google map demo, we hack this problem a bit as we listen for the change event on the text field.

Changing the change event behavior is not an option, the autocomplete value and autocomplete input value are two independent states. The alternative I can think of is to provide a dedicated prop for the data fetching prop. For instance, react-autosuggest has a onSuggestionsFetchRequested prop, EUI has a onSearchChange prop or Antd has an onSearch prop.

I think that we can add a third argument to the onInputChange callback: reason. It could either be "input" when coming from user interaction or "reset" after the value change. Would this work for you? Do you want to work on a pull request?

@oliviertassinari Ah switching the order makes sense to me. I did notice they fired in reverse order than I initially expected. You're right though, it wouldn't completely solve this issue since onChange is firing on select as well.

I think adding a reason argument makes the most sense here. It provides an option to only take action on user input, solving my issue, and also adds a lot of flexibility for other implementations. I can take a stab at a pull request. I think I should have time to get something up this weekend!

Turns out I had some extra time this afternoon to add the reason argument. PR up above!

@Tybot204 Loving it, thank you

@oliviertassinari reason is ok, but input value is changed automatically.
How to prevent this?

selectNewValue calls resetInputValue and it's automatically change input's value setInputValue(newInputValue);

What if I don't want to do that?
There is no any any flag to prevent that and control input by yourself.

@eawtf Control the inputValue state, ignore the reset event.

One of the possible solution to prevent executing onInputChange while onChange getting executed.

onInputChange={(e, value) => {
   e && e.constructor.name === "SyntheticEvent" && fetchData(value)
}}

Here, fetchData will only get executed on keypress event.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sys13 picture sys13  路  3Comments

activatedgeek picture activatedgeek  路  3Comments

mattmiddlesworth picture mattmiddlesworth  路  3Comments

FranBran picture FranBran  路  3Comments

anthony-dandrea picture anthony-dandrea  路  3Comments