3

I am unable to clear the value of a material-ui Input using refs, not state.

I've tried both types of refs that I know about: ref={this.input} - and - ref={el => (this.input = el)}

but neither seems to work w/ a material-ui Input

the following similar questions did not help: How to get input value of TextField from Material UI? Clear and reset form input fields Clear an input field with Reactjs? how to set Input value in formField ReactJs

Here's a snippet of my React JSX for the input & button:

    <Input
      type="text"
      id="name"
      inputComponent="input"
      ref={el => (this.name = el)}
    />
    <Button
      variant="contained"
      onClick={this.handleClear}
      className="materialBtn"
    >
      Clear
    </Button>

And the event handler that I expect should clear the input value:

    handleClear() {
      this.name.value = "";
    }

I can make the code work fine using a standard HTML5 input, but not with a material-ui input, which is a requirement of this project. Additionally, this element's value is NOT in react state and I am not looking for a solution that requires using state -- I need to keep this piece as an uncontrolled component.

What am I missing w/ regard to material-ui? I have combed their docs/api but haven't found anything that suggests it needs to be handled differently from a standard input. thanks

Here's an example on CodeSandbox showing the failure w/ a material-ui input and success w/ an HTML5 input: https://codesandbox.io/s/fancy-frost-joe03

Coder
  • 33
  • 1
  • 1
  • 3

2 Answers2

6

I figured it out, you are using the wrong prop for the ref. You should be using inputRef prop. Here is the correct version,

<Input
    type="text"
    id="name"
    inputComponent="input"
    inputRef={el => this.name = el}           
/>
<Button
    variant="contained"
    onClick={this.handleClear}
    className="materialBtn"
>
 Clear
</Button>
handleClear() {
      this.name.value = "";
    }

The reason is that the Material Input component creates an element with the following structure,

<div class="MuiInputBase-root MuiInput-root MuiInput-underline">
<input class="MuiInputBase-input MuiInput-input" id="name" type="text" value=""></input>
</div>

So, using ref would reference the root element which is <div>. So, they created a separate prop called inputRef to reference the child element <input>.

I updated your codesandbox.io code and saved it. Check out the full working code here,

https://codesandbox.io/s/elastic-dhawan-l4dtf

Ramaraja
  • 2,526
  • 16
  • 21
  • 1
    Wow, it never occurred to me that Material-UI prevents a React ref from working as designed. It would have been helpful if the documentation had gone to the trouble of stating that inputRef must be used *in place of* a standard React ref. Thank you for your insight. – Coder Aug 08 '19 at 22:53
  • 1
    @Coder True, it is a bit unconventional. I happened to figure it out by looking at the API [here](https://material-ui.com/api/input/). The reason is that the Material Input component creates an element with the structure ```
    ```, so using ref would reference the root element which is
    . So, they created a separate prop called inputRef to reference the child element . I have updated the answer with this explanation
    – Ramaraja Aug 09 '19 at 07:03
  • I keep forgetting to use inputRef as opposed to ref. – andromeda Oct 26 '21 at 17:42
1
import React, { useState } from 'react'
    
import { Button, Container, InputBase } from '@material-ui/core'


const ClearText = ()=> {
    const [text , setText] = useState("")
}

const clearTextField = () => setText("")

    return (
        <Container>
        <InputBase 
        value={text ? text : ""}
        onChange={(e)=>setText(e.target.value)}
        />


        <Button onClick={clearTextField} > Clear </Button>
        </Container>
    )
};

export default ClearText;
Vimal Patel
  • 2,785
  • 2
  • 24
  • 38
  • 1
    Welcome to Stack Overflow. Code is a lot more helpful when it is accompanied by an explanation. Stack Overflow is about learning, not providing snippets to blindly copy and paste. Please [edit] your question and explain how it answers the specific question being asked. See [answer]. – ChrisGPT was on strike Dec 11 '21 at 04:21