Coder
Coder

Reputation: 43

How to set or clear value of material-ui Input in ReactJS

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

Upvotes: 4

Views: 13012

Answers (2)

beforeitstoolate
beforeitstoolate

Reputation: 11

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;

Upvotes: 1

Ramaraja
Ramaraja

Reputation: 2626

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

Upvotes: 6

Related Questions