Hacker News new | past | comments | ask | show | jobs | submit login

>Are there any other known anti-patterns left in React?

String refs and `findDOMNode()`. Both are anti-patterns but not deprecated yet. Both replaced by callback refs.

Could you expand on string refs as an anti-pattern?

I wouldn't necessarily call them an anti-pattern, but they are at the very least not encouraged:

> Although string refs are not deprecated, they are considered legacy, and will likely be deprecated at some point in the future. Callback refs are preferred.[1]

I'm still using them in React Native, because I'm new and didn't realise there was an alternative until recently. To me there are three issues:

1. Magic. All you do is specify a string and somehow you end up with this.refs.<name>. Admittedly not that hard to follow, but magic is generally bad.

2. It's hard to keep track of what refs actually exist, which makes naming collisions hard to notice. There's just some arbitrary string in some JSX. Using explicit properties means they can be tracked much more easily e.g. Flow.

3. Again related to Flow, if you're declaring your properties as you should be, then Flow will tell you if swapping a referenced component type (checkbox for switch etc.) is going to cause problems elsewhere in code.

EDIT: I suppose you could already be declaring your refs with Flow. However, if you're doing that you're already 90% the way to using dedicated properties. In which case you might as well eliminate the magic and just use your own properties, rather than properties on refs. This makes searching for usage/references much more obvious; people/IDEs generally don't think of strings being a reference to a variable.

[1] https://facebook.github.io/react/docs/more-about-refs.html

I'd like an answer to this as well. I've only ever needed string refs, and the callback refs are noisy. I can see where the React team may not want to support both, but are string refs actually bad in some way?

String refs are bad in quite a few ways:

1. String refs are not composable. A wrapping component can’t “snoop” on a ref to a child if it already has an existing string ref. On the other hand, callback refs don’t have a single owner, so you can always compose them.

2. String refs don’t work with static analysis like Flow. Flow can’t guess the magic that framework does to make the string ref “appear” on `this.refs`, as well as its type (which could be different). Callback refs are friendlier to static analysis.

3. The owner for a string ref is determined by the currently executing component. This means that with a common “render callback” pattern (e.g. `<DataTable renderRow={this.renderRow} />`), the wrong component will own the ref (it will end up on `DataTable` instead of your component defining `renderRow`).

4. String refs force React to keep track of currently executing component. This is problematic because it makes `react` module stateful, and thus causes weird errors when `react` module is duplicated in the bundle.

This is why we want to move away from them in favor of callback refs that solve all those problems.

I think it's important people understand this. The last two points are precisely the reason String refs got moved from Preact's core into preact-compat.

Also, for the common-case usage of string refs, you can just use a helper to insert things into `this.refs`:


Thanks for the thorough answer, Dan.

(Had I not followed the prescription for the sake of being future-proof, I probably would have had a painful debugging session over #3. And possibly #1 too.)

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact