51

If I have just a basic forms, should I still this.refs or just go with document.getElementById?

By basic I mean something like:

export default class ForgetPasswordComponent extends React.Component {
  constructor(props) {
    super(props);

    this.handleSendEmail = this.handleSendEmail.bind(this);
  }

  handleSendEmail(e) {
    e.preventDefault();

    // this.refs.email.value
    // document.getElementById('email').value
  }

  render() {
    <form onSubmit={this.handleSendEmail}>
      <input id="email" ref="email" type="text" />
      <input type="submit" />
    </form>
  }
}

Is there a downside into using one over the other?

index
  • 3,697
  • 7
  • 36
  • 55
  • 3
    If you have multiple instances of the the ForgetPasswordComponent within a single page or if you have any other elements with the id 'email' there is a chance the wrong element might get selected. – Isuru May 17 '16 at 10:49
  • If I make ids as unique as possible (since id's should be unique in html anyway) should I still go for refs or ids? Is there a downside to using refs? – index May 17 '16 at 11:08
  • related: http://stackoverflow.com/questions/38093760/in-react-js-is-there-any-function-similar-like-document-getelementbyid-in-ja – James Gentes Mar 13 '17 at 18:24

1 Answers1

69

In general, refs is better than document.getElementById, because it is more in line with the rest of your react code.

In react, every component class can have multiple component instances.
And as @Isuru points out in comments: using id is dangerous, because react does not prevent you to have multiple forms on 1 page, and then your DOM contains multiple inputs with same ID. And that is not allowed.

Another advantage to using refs, is that by design, you can only access the refs in the context where you define it. This forces you to use props and state (and possibly stores) if you need to access info outside of this context.
And this an advantage, because there is less/ no chance of you breaking your unidirectional data flow, which would make your code less manageable.

NB: In almost all cases, refs can be avoided altogether. It is a design principle for Netflix to use no refs, ever, as explained by Steve McGuire (Senior User Interface Engineer at Netflix) in this video from reactjs conf 2016 (9:58m into the video).
In your case, this would mean putting the email-input value in state of the form, add on onChange handler, and use the state value in the submit event.

wintvelt
  • 13,855
  • 3
  • 38
  • 43
  • 3
    +1 for mentioning that in most cases you don't need to use either of them, but should use value + onChange (or LinkedStateMixin). – Björn Boxstart May 17 '16 at 11:35
  • 1
    I've read about the use of state and I'm just a bit hesitant to use it because of a lot of implementation like adding `value`, `onchangevalue`, `state` and when there's a lot of fields in the form you'd start to have a lot of those. Hehe. So is it really prefered to use value + state + onchange? – index May 18 '16 at 03:37
  • Yes, it is preferred over refs. Refs are a shortcut and likely to get you into debugging nightmare as your app grows. – wintvelt May 18 '16 at 05:53
  • 4
    Refs can also increase the complexity of what you are trying to do if they start getting passed down to children through props. If you are doing something like a nested scroll to top button I would recommend using document.getElement.. it will be cleaner, indicative of intention and isn't involving state related actions. You may want to put a check in to confirm that the target element exists before calling scrollTo on it though. For things like forms however, I would highly recommend avoiding refs or document.getElement and finding a way to structure things with state. – Jax Cavalera Feb 05 '18 at 23:27
  • 2
    Ironically, Elijah Meeks, head of datavis at Netflix, **recommends the use of refs** when combining React + D3 in his 2017 discussion of the subject: https://medium.com/@Elijah_Meeks/interactive-applications-with-react-d3-f76f7b3ebc71 – duhaime Sep 13 '20 at 20:15
  • 1
    Haha, yeah lots of developments since this question and answer. Using material-ui nowadays, forward refs and the useRef hook are more or less commonplace. I’m the context of this question, I still think it’s still better not to use refs. But I guess the “never use refs” rule is no longer a hard rule. ;) – wintvelt Sep 13 '20 at 20:47