[SOLVED] Proper type to use in useRef for Material-UI TextField

Issue

This Content is from Stack Overflow. Question asked by Gabriel Ratener

Using react hooks with Material-UI and TypeScript I’m unable to find a proper type T for the Material-UI TextField component. Therefore I am resorting to using HTMLInputElement as the RefObject T parameter because it also has a focus method.

  const focus = (inputRef: RefObject<HTMLInputElement>) => {
    if (inputRef.current !== null) {
      inputRef.current.focus()
    }
  }

What replacement of HTMLInputElement will work properly for representing the TextField API in the RefObject in this case? I was hoping Material-UI would export something like “TextFieldRef” at least, but that doesn’t seem to be the case.

Thanks in advance!



Solution

First of all, it really depends on what are you trying to achieve.
are you trying to focus the input of the text field or the root element?

from MUI docs:

The ref is forwarded to the root element.

to get a ref to the <input /> element you should use the inputRef prop. You can read about it here.
In this case, you shall indeed use the HTMLInputElement since it is an input behind the scenes.


Let’s dive into mui code base:

TextField code base indeed reveals an InputComponent which receive the inputRef prop.

In case you do want to get a ref to to root element, we can see that TextFieldRoot component is the root element which receive the ref.
line 179:

    <TextFieldRoot
      className={clsx(classes.root, className)}
      disabled={disabled}
      error={error}
      fullWidth={fullWidth}
      ref={ref}
      required={required}
      color={color}
      variant={variant}
      ownerState={ownerState}
      {...other}
    >

so lets explore where does it get from.
we can see it is a styled FormControl component. from line 33:

const TextFieldRoot = styled(FormControl, {
  name: 'MuiTextField',
  slot: 'Root',
  overridesResolver: (props, styles) => styles.root,
})({});

From FormControl code we can understand that FormControlRoot root receive the ref as prop, line 215:

  return (
    <FormControlContext.Provider value={childContext}>
      <FormControlRoot
        as={component}
        ownerState={ownerState}
        className={clsx(classes.root, className)}
        ref={ref}
        {...other}
      >
        {children}
      </FormControlRoot>
    </FormControlContext.Provider>
  );
});

and finally, from line 22 we can understand it is just a styled div..

const FormControlRoot = styled('div', { 
...

So now, based on MUI base code, you can choose between HTMLInputElement and HTMLDivElement by your needs.


This Question was asked in StackOverflow by Gabriel Ratener and Answered by Yarin Barnes It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?