Repository: mui/material-ui (TypeScript) — Bug Fix

Issue:
[Select] node is undefined
<!-- Checked checkbox should look like this: [x] -->
- [ x ] This is not a v0.x issue. <!-- (v0.x is no longer maintained) -->
- [ 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.

## Expected Behavior 🤔
The expected behavior is to get the node target of an text field with select={true}.

## Current Behavior 😯
If you pass down a ref to a TextField by using inputProps, you will get the select component. 
This object has a node key. But in the latest version of material-ui it is always empty.
We use it for field validations.

## Steps to Reproduce 🕹
Visit this sandbox and open your console. If you change now the value of the select, you will see that the node key has a value (if you are using 3.9.3). But if you switch to 4.1.1 and repeat the task, then you see that the node key has no value.

https://codesandbox.io/s/vigorous-http-c7x5j

Big thanks for your help!

## Your Environment 🌎
| Tech         | Version |
|--------------|---------|
| Material-UI  | v4.1.1  |
| React        |  16.8.6       |
| Browser      |  Chrome       |
| TypeScript   |  no       |
| etc.         |         |



Discussion:
@ffjanhoeck Thanks for the report. This looks like a regression to me. What do you think of this fix?
```diff
diff --git a/packages/material-ui/src/Select/SelectInput.js b/packages/material-ui/src/Select/SelectInput.js
index 6ea5b3959..5c8cedd24 100644
--- a/packages/material-ui/src/Select/SelectInput.js
+++ b/packages/material-ui/src/Select/SelectInput.js
@@ -27,7 +27,7 @@ const SelectInput = React.forwardRef(function SelectInput(props, ref) {
     disabled,
     displayEmpty,
     IconComponent,
-    inputRef,
+    inputRef: inputRefProp,
     MenuProps = {},
     multiple,
     name,
@@ -48,12 +48,14 @@ const SelectInput = React.forwardRef(function SelectInput(props, ref) {
     ...other
   } = props;
   const displayRef = React.useRef(null);
+  const inputRef = React.useRef(null);
   const ignoreNextBlur = React.useRef(false);
   const { current: isOpenControlled } = React.useRef(openProp != null);
   const [menuMinWidthState, setMenuMinWidthState] = React.useState();
   const [openState, setOpenState] = React.useState(false);
   const [, forceUpdate] = React.useState(0);
-  const handleRef = useForkRef(ref, inputRef);
+  const handleInputRef = useForkRef(inputRef, inputRefProp);
+  const handleRef = useForkRef(ref, handleInputRef);

   React.useImperativeHandle(
     handleRef,
@@ -61,10 +63,10 @@ const SelectInput = React.forwardRef(function SelectInput(props, ref) {
       focus: () => {
         displayRef.current.focus();
       },
-      node: inputRef ? inputRef.current : null,
+      node: inputRef.current,
       value,
     }),
-    [inputRef, value],
+    [value],
   );

   React.useEffect(() => {
```

Do you want to submit a pull request? :)
@oliviertassinari Thanks for your answer! I would love it to submit a pull request!
But before I can submit my first one, I have some questions:
- Why do you manipulate the value of the ref using useImperativeHandle. Is that really necessary? 
- Does it make sense in your opinion, to directly pass the ref into the input, without useForkRef and useImperativeHandle? I don't get it, why you are using this :)

Thank you and have a good day!
@ffjanhoeck Yes, useImperativeHandle and all the "mess" that comes with it is really necessary, there is no simplification potential I'm aware of. There is no input we can apply the ref on. We have to simulate it.
@oliviertassinari What is the best way to test the change?
Do you always setup a new project to test your components or do you just write tests?

EDIT: Nevermind, I have found this: https://github.com/mui-org/material-ui/blob/master/CONTRIBUTING.md
@oliviertassinari I fixed the bug, but in a other way as your example. Never mind, I cannot push my change to a new branch. I always get the error, that I don't have permissions. I did in the same way, like the documentation describes it.

Do you know what I do wrong?

![image](https://user-images.githubusercontent.com/9037364/59789137-a246a300-92cd-11e9-8c65-6f5d8fd1ed28.png)

@ffjanhoeck You need to fork the repo and create a pull request from your fork :)
@joshwooding Thanks for your advice :) I directly cloned the repo. Let me try the way with the fork :)

Resolving patch:
diff --git a/packages/material-ui/src/Select/SelectInput.js b/packages/material-ui/src/Select/SelectInput.js
--- a/packages/material-ui/src/Select/SelectInput.js
+++ b/packages/material-ui/src/Select/SelectInput.js
@@ -27,7 +27,7 @@ const SelectInput = React.forwardRef(function SelectInput(props, ref) {
     disabled,
     displayEmpty,
     IconComponent,
-    inputRef,
+    inputRef: inputRefProp,
     MenuProps = {},
     multiple,
     name,
@@ -47,13 +47,16 @@ const SelectInput = React.forwardRef(function SelectInput(props, ref) {
     variant,
     ...other
   } = props;
+
+  const inputRef = React.useRef(null);
   const displayRef = React.useRef(null);
   const ignoreNextBlur = React.useRef(false);
   const { current: isOpenControlled } = React.useRef(openProp != null);
   const [menuMinWidthState, setMenuMinWidthState] = React.useState();
   const [openState, setOpenState] = React.useState(false);
   const [, forceUpdate] = React.useState(0);
-  const handleRef = useForkRef(ref, inputRef);
+  const handleInputRef = useForkRef(inputRef, inputRefProp);
+  const handleRef = useForkRef(ref, handleInputRef);
 
   React.useImperativeHandle(
     handleRef,
@@ -61,10 +64,10 @@ const SelectInput = React.forwardRef(function SelectInput(props, ref) {
       focus: () => {
         displayRef.current.focus();
       },
-      node: inputRef ? inputRef.current : null,
+      node: inputRef.current,
       value,
     }),
-    [inputRef, value],
+    [value],
   );
 
   React.useEffect(() => {


Test patch:
diff --git a/packages/material-ui/src/Select/SelectInput.test.js b/packages/material-ui/src/Select/SelectInput.test.js
--- a/packages/material-ui/src/Select/SelectInput.test.js
+++ b/packages/material-ui/src/Select/SelectInput.test.js
@@ -419,6 +419,12 @@ describe('<SelectInput />', () => {
     });
   });
 
+  it('should be able to return the input node via a ref object', () => {
+    const ref = React.createRef();
+    mount(<SelectInput {...defaultProps} ref={ref} />);
+    assert.strictEqual(ref.current.node.tagName, 'INPUT');
+  });
+
   describe('prop: inputRef', () => {
     it('should be able to return the input node via a ref object', () => {
       const ref = React.createRef();