Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Material UI component reference does not work

I am building a little chat application.i have used Material UI TextField to input user message. but i can't refer it. I read about this. they said that they do not support for refs. this is my code. and it works.

class App extends Component {
  constructor() {
    super();
    this.state = {
      q: "default"
    };

  }
  handleChanges(val) {
    this.setState({ q: val });
  }
  handleSearch(val) {
    this.setState({ q: val });
    console.log(this.state.q);
  }
  render() {
    return (
      <div className="App">
        <h1>  {this.state.q}</h1>
        <Row className="show-grid">
          <Col sm={2} md={4} className="contact"><h5>contact</h5><br /></Col>
          <Col sm={10} md={8} className="chat grid-border"><h5>chat</h5><br />
            <div className="history"></div>
            <div className="message top-border">

              <input type="text" ref="question" onChange={(e) => { this.handleChanges(this.refs.question.value) }} />
              <MuiThemeProvider>
                <FlatButton label="Primary" primary={true} onTouchTap={(e) => { e.preventDefault(); this.handleSearch(this.refs.question.value); }} />
              </MuiThemeProvider>

            </div>
          </Col>
        </Row>{/*show-grid ends here*/}
      </div>
    );
  }
}
export default App;

If i used this material UI TextField instead of native HTML input tag it does not get the value from the reference.

<MuiThemeProvider>
       <TextField hintText="Ask your question" fullWidth={true} multiLine={true} rows={2} rowsMax={4} type="text" ref="question" onChange={(e) => { this.handleChanges(this.refs.question.value) }}/>
</MuiThemeProvider> 

Is there any workaround or alternative UI library for this ?

like image 583
isuruAb Avatar asked May 14 '17 03:05

isuruAb


Video Answer


5 Answers

You can also use inputRef. This prop is available from material 1.0.

<TextField
   className={classes.textField}
   inputRef={input => (this._my_field = input)}
   label="My field"
   fullWidth
   margin="normal"
   defaultValue={this.props.my_field}
   onChange={this.handleChange("dhis_password")}
/>

The on change let’s you update the state when it changes, but if you need to get the value unchanged, then the inputRef is necessary.

Also have a look at You can see this How to get password field value in react's material-ui

like image 90
Kushal Jain Avatar answered Oct 19 '22 10:10

Kushal Jain


Try the following

    let emailRef =React.createRef();

in the material-ui input field use inputRef

 <TextField label="Email Address" name="email" inputRef ={emailRef} />

Just use inputRef not ref

like image 28
Khaled Hosni Avatar answered Oct 19 '22 10:10

Khaled Hosni


if you are using a stateless functional component with material ui then you can use react hooks.

import React, { useState, useRef } from "react";

let MyComponent = (props) => {

  let textInput = useRef(null);

  return (
    <div>
      <Button
        onClick={() => {
          setTimeout(() => {
            textInput.current.focus();
            textInput.current.click();
            textInput.current.value="myname";
          }, 100);
        }}
      >
        Focus TextField
      </Button>
      <TextField
        fullWidth
        required
        inputRef={textInput}
        name="firstName"
        type="text"
        placeholder="Enter Your First Name"
        label="First Name"
      />
    </div>
  );
};
like image 4
44kksharma Avatar answered Oct 19 '22 08:10

44kksharma


This way of referencing elements is deprecated. See https://facebook.github.io/react/docs/refs-and-the-dom.html

Try using this:

<TextField hintText="Ask your question" fullWidth={true} multiLine={true} rows={2} rowsMax={4} type="text" ref={(input) => { this.input = input; }} onChange={(e) => { this.handleChanges(this.refs.question.value) }}/>

And reference the TextField as this.input

If you want to get the TextField value, use this.input.getValue()

I did something like that here.

like image 3
Pablo Darde Avatar answered Oct 19 '22 10:10

Pablo Darde


In onChange method, you don't need to use ref to access value of same textfield, material-ui TextField pass 2 parameters in onChange method:

event, value

So you can write it like this without using ref:

<TextField ... onChange={(e, value) =>  this.handleChanges(value) }/>

As per DOC:

onChange: function

Callback function that is fired when the textfield's value changes.

Signature: function(event: object, newValue: string) => void

event: Change event targeting the text field.

newValue: The new value of the text field.

like image 1
Mayank Shukla Avatar answered Oct 19 '22 09:10

Mayank Shukla