Repository: mui/material-ui (TypeScript)
Date: 2019-11-26 02:33:46+00:00
Task type: Bug Fix

Issue:
[Autocomplete] onInputChange it's fired in wrong moments
I don't know if I'm not understanding how it works or it's a bug, but onInputChange is executed when the component is mounted and when the TextField loses the focus.

- [x] The issue is present in the latest release.
- [x] I have searched the [issues](https://github.com/mui-org/material-ui/issues) of this repository and believe that this is not a duplicate.

## Current Behavior 😯
onInputChange is been fired when the component is mounted and when the TextField loses the focus.

## Expected Behavior 🤔
onInputChange has to be fired only when the TextField has really fired

## Steps to Reproduce 🕹
Steps:

1. [codesandbox.io reproduction](https://codesandbox.io/s/autocomplete-oninputchange-it696)
2. The alert shows up when the page is fully loaded.
3. Click on the TextField and then click outside.
4. The alert shows up again.

## Your Environment 🌎

<!--
  Include as many relevant details about the environment with which you experienced the bug.
  If you encounter issues with typescript please include version and tsconfig.
-->

| Tech        | Version |
| ----------- | ------- |
| Material-UI | v4.7.0  |
| React       |v16.10.2|
| Browser     |Chrome v78.0.3904.108 (64 bits)|



Issue discussion:
@sclavijo93 How does it cause an issue in your end?
I guess we could only trigger the event if the value actually changes. Would it solve your problem?

```diff
diff --git a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
index f833a0c0c..cc44ea60a 100644
--- a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
+++ b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
@@ -210,6 +210,10 @@ export default function useAutocomplete(props) {
       newInputValue = typeof optionLabel === 'string' ? optionLabel : '';
     }

+    if (inputValue === newInputValue) {
+      return;
+    }
+
     setInputValue(newInputValue);

     if (onInputChange) {
@@ -635,6 +639,10 @@ export default function useAutocomplete(props) {
       handleOpen(event);
     }

+    if (inputValue === newValue) {
+      return;
+    }
+
     setInputValue(newValue);

     if (onInputChange) {
```
@oliviertassinari it's referenced by #18559 because I'm trying to show the `CircularProgress`  when the user types in the text field, but right now the `CircularProgress` is showed not only when the user types

Solution patch:
diff --git a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
--- a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
+++ b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
@@ -210,6 +210,10 @@ export default function useAutocomplete(props) {
       newInputValue = typeof optionLabel === 'string' ? optionLabel : '';
     }
 
+    if (inputValue === newInputValue) {
+      return;
+    }
+
     setInputValue(newInputValue);
 
     if (onInputChange) {
@@ -635,6 +639,10 @@ export default function useAutocomplete(props) {
       handleOpen(event);
     }
 
+    if (inputValue === newValue) {
+      return;
+    }
+
     setInputValue(newValue);
 
     if (onInputChange) {


Test patch:
diff --git a/packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js b/packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js
--- a/packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js
+++ b/packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js
@@ -650,11 +650,10 @@ describe('<Autocomplete />', () => {
       const { getByRole } = render(<MyComponent />);
 
       const textbox = getByRole('textbox');
-      expect(handleChange.callCount).to.equal(1);
-      expect(handleChange.args[0][0]).to.equal('');
+      expect(handleChange.callCount).to.equal(0);
       fireEvent.change(textbox, { target: { value: 'a' } });
-      expect(handleChange.callCount).to.equal(2);
-      expect(handleChange.args[1][0]).to.equal('a');
+      expect(handleChange.callCount).to.equal(1);
+      expect(handleChange.args[0][0]).to.equal('a');
       expect(textbox.value).to.equal('');
     });
   });