Repository: mui/material-ui (TypeScript)
Date: 2020-05-25 03:32:13+00:00
Task type: Bug Fix

Issue:
[Autocomplete] An error occurs when changing multiple
- [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
An error occurs when changing multiple
`
A component is changing the default value state of an uncontrolled Autocomplete after being initialized. To suppress this warning opt to use a controlled Autocomplete. 
`
# Expected Behavior
No error
# Steps to Reproduce
https://codesandbox.io/s/solitary-http-e0zzh?file=/App.js


Issue discussion:
👋 Thanks for using Material-UI!

We use GitHub issues exclusively as a bug and feature requests tracker, however,
this issue appears to be a support request.

For support, please check out https://material-ui.com/getting-started/support/. Thanks!

If you have a question on StackOverflow, you are welcome to link to it here, it might help others.
If your issue is subsequently confirmed as a bug,  and the report follows the issue template, it can be reopened.
Tip: stick to what the warning says, you will solve the problem. 
What can i do?
Would you give me more information?
@weizhi9958 You are right, the warning shouldn't be thrown in this context. Thanks for the report. What do you think of this patch?

```diff
diff --git a/packages/material-ui/src/utils/useControlled.js b/packages/material-ui/src/utils/useControlled.js
index dab0f9039..730ccb30a 100644
--- a/packages/material-ui/src/utils/useControlled.js
+++ b/packages/material-ui/src/utils/useControlled.js
@@ -27,7 +27,7 @@ export default function useControlled({ controlled, default: defaultProp, name,
     const { current: defaultValue } = React.useRef(defaultProp);

     React.useEffect(() => {
-      if (defaultValue !== defaultProp) {
+      if (!isControlled && defaultValue !== defaultProp) {
         console.error(
           [
             `Material-UI: A component is changing the default ${state} state of an uncontrolled ${name} after being initialized. ` +
@@ -35,7 +35,7 @@ export default function useControlled({ controlled, default: defaultProp, name,
           ].join('\n'),
         );
       }
    }, [JSON.stringify(defaultProp)]);
   }

   const setValueIfUncontrolled = React.useCallback((newValue) => {
```

Do you want to submit a pull request? :)
maybe could be better to check `JSON.stringify` of both attribute.
`if (!isControlled && JSON.stringify(defaultValue) !== JSON.stringify(defaultProp)) { `
@marcosvega91 I don't know. I believe we use `JSON.stringify` here to support people that provide rich default objects. What would this change help to achieve?
Thinking better you are right. Never mind 😃 

Solution patch:
diff --git a/packages/material-ui/src/utils/useControlled.js b/packages/material-ui/src/utils/useControlled.js
--- a/packages/material-ui/src/utils/useControlled.js
+++ b/packages/material-ui/src/utils/useControlled.js
@@ -27,7 +27,7 @@ export default function useControlled({ controlled, default: defaultProp, name,
     const { current: defaultValue } = React.useRef(defaultProp);
 
     React.useEffect(() => {
-      if (defaultValue !== defaultProp) {
+      if (!isControlled && defaultValue !== defaultProp) {
         console.error(
           [
             `Material-UI: A component is changing the default ${state} state of an uncontrolled ${name} after being initialized. ` +


Test patch:
diff --git a/packages/material-ui/src/utils/useControlled.test.js b/packages/material-ui/src/utils/useControlled.test.js
--- a/packages/material-ui/src/utils/useControlled.test.js
+++ b/packages/material-ui/src/utils/useControlled.test.js
@@ -83,4 +83,15 @@ describe('useControlled', () => {
       'Material-UI: A component is changing the default value state of an uncontrolled TestComponent after being initialized.',
     );
   });
+
+  it('should not raise a warning if changing the defaultValue when controlled', () => {
+    const { setProps } = render(
+      <TestComponent value={1} defaultValue={0}>
+        {() => null}
+      </TestComponent>,
+    );
+    expect(consoleErrorMock.callCount()).to.equal(0);
+    setProps({ defaultValue: 1 });
+    expect(consoleErrorMock.callCount()).to.equal(0);
+  });
 });