6

I am using semantic-ui-react's Form.Input, which wraps the input in two divs.

This means,

<Form.Input type='password' name='password' id='loginPassword'></Form.Input>

is rendered as follows:

<div class='field'>
  <div class='ui fluid action left icon input'>
   <input type='password' name='password' id='loginPassword' ...>
   <button ...>
  </div>
</div>

I would like to get the ref for the <input/> element, so that I can call focus().

  1. My ref is set to the component when using ref='myRef'
  2. ReactDOM.findDOMNode returns a DOM ref, but the ref is set to the outer div (with class='field').

How do I get a ref to the <input/> element?

BTW, I am using redux, although I don't think that matters

mdebeus
  • 1,928
  • 3
  • 18
  • 27

2 Answers2

8

Form.Input is just a shorthand for some components that are wrapping an Input. So behind the scenes this:

<Form.Input label='Enter Password' type='password' />

Is the same as this:

<Form.Field>
  <label>Enter Password</label>
  <Input type='password' />
</Form.Field>

semantic-ui-react supports the react ref API for Input, but make sure you are using the current ref API and not the old one:

<Input ref={ref => this.input = ref} />

running example:

const { Input, Button } = semanticUIReact; // import

class App extends React.Component {
  onClick = () => this.input.focus();
  render() {
    return (
      <div>
        <Input ref={ref => this.input = ref} />
        <Button onClick={this.onClick}>Focus</Button>
      </div>
    );
  }
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/semantic-ui-react@0.78.3/dist/umd/semantic-ui-react.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.9/semantic.min.css"/>
 <div id="root"></div>
Sagiv b.g
  • 30,379
  • 9
  • 68
  • 99
  • 1
    Thank you, but this did not really help the problem at all - I can get the ref. Also, I am using Form.Input, not Input, so the ref I get is a ref to the divs that surround the input, not the input itself, which is what I wanted. However, Ben gave me a good solution. – mdebeus Mar 05 '18 at 22:38
  • As i mentioned in my answer, `Form.Input` is a shorthand for multiple components. You can use the "normal" structure if you really need the ref. If you are ok with querying the dom go for it – Sagiv b.g Mar 05 '18 at 22:42
  • I see - it wasn't clear to me what you meant by shorthand for multiple components - now I get it. I really want the Form.Input version, so querying the DOM works. However, it is good to know that the other version is available when I need it. – mdebeus Mar 05 '18 at 23:29
  • 1
    This one should be selected as proper one. – Damian Przygodzki Jul 22 '19 at 10:20
-2

As you're using findDOMnode (usually not advised), you're back into standard js, so this :

ReactDOM.findDOMNode(your ref).querySelector('input')

should work

Ben
  • 5,030
  • 6
  • 53
  • 94
  • Thank you - this did the trick. Since I have no control over the component, I am stuck using this option : [ https://reactjs.org/docs/refs-and-the-dom.html] All things considered, we advise against exposing DOM nodes whenever possible, but this can be a useful escape hatch. Note that this approach requires you to add some code to the child component. If you have absolutely no control over the child component implementation, your last option is to use findDOMNode(), but it is discouraged. – mdebeus Mar 05 '18 at 22:35