Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible removal of findDOMNode() from React in a future version #251

Open
ducky427 opened this issue Jul 12, 2016 · 20 comments
Open

Possible removal of findDOMNode() from React in a future version #251

ducky427 opened this issue Jul 12, 2016 · 20 comments

Comments

@ducky427
Copy link
Contributor

ducky427 commented Jul 12, 2016

There are rumblings in the React world of deprecating findDOMNode() which is equivalent to Reagent's reagent.core/dom-node.

@gaearon also tweeted about it here.

We may want to start planning for this in a future release.

@ducky427 ducky427 changed the title Possible removal of findDOMNode() from React Possible removal of findDOMNode() from React in a future version Jul 12, 2016
@Frozenlock
Copy link

This is making me uneasy... I'm a heavy user of dom-node. I like being able to get my hands on the dom element.

@gaearon
Copy link

gaearon commented Jul 12, 2016

To be clear React still provides a way to get the node: with callback refs. I’m not sure how that would translate to your API but jsx-eslint/eslint-plugin-react#678 has some React examples for better alternative patterns.

@ducky427
Copy link
Contributor Author

ducky427 commented Jul 12, 2016

@Frozenlock, its actually pretty straight forward to get the actual dom element as @gaearon mentions.

I'll post a very simple example of this in reagent.

@ducky427
Copy link
Contributor Author

ducky427 commented Jul 12, 2016

This example illustrates how to avoid using React's findDOMNode:

(defn hello-component
  []
  (let [dom-node (atom nil)]
    (reagent/create-class
     {:component-did-mount (fn [x] (js/console.log @dom-node))
      :reagent-render (fn [x] [:h2 {:ref (fn [y] (reset! dom-node y))} "hello"])})))

Note: dom-node is a clojurescript atom and not a reagent atom.

Repo with this code is here.

Edit: I've removed :component-will-unmount (fn [] (reset! dom-node nil)) after comment by @Frozenlock.

@bhauman
Copy link

bhauman commented Jul 12, 2016

Wow that is easy AND straight forward...

@gaearon
Copy link

gaearon commented Jul 12, 2016

@Frozenlock
Copy link

Looks simple enough.

I wasn't aware of the :ref field.
If it doesn't have too many gotchas it could be the way going forward.
Is it necessary to have it at the top level in a component?

@ducky427
Copy link
Contributor Author

@Frozenlock,

Regarding ref:

React supports a special attribute that you can attach to any component. The ref attribute can be a callback function, and this callback will be executed immediately after the component is mounted. The referenced component will be passed in as a parameter, and the callback function may use the component immediately, or save the reference for future use (or both).

More here.

So basically, you can place any function in ref. In my example, I created a function which just captures the referenced component in an atom. That atom didn't needn't be where it is.

Hope this makes sense.

@Frozenlock
Copy link

It does. If I understand correctly, it's a much simpler :component-did-mount.

Also, it appears that the unmounting function in the example is superfluous:

Note that when the referenced component is unmounted and whenever the ref changes, the old ref will be called with null as an argument. This prevents memory leaks in the case that the instance is stored, as in the second example.

@ducky427
Copy link
Contributor Author

@Frozenlock, that's true. I didn't realise that. I'll fix my example

@bskimball
Copy link

Is there an alternative for ReactDOM.findDOMNode (this.element).getClientBoundingRect ()?

@gaearon
Copy link

gaearon commented Aug 7, 2016

What is this.element?

@everdimension
Copy link

everdimension commented Mar 14, 2017

I think ref={n => this.el = n} is not an alternative to findDOMNode.

Let's say I want to create a <HashAnchor id="something" /> component which would accept any element (or component) as its child. Upon mount it would get the underlying dom node, calculate it's offset and if it's id matches the location.hash then it mount scroll it's child into browser's view.

I would use it like this:

<HashAnchor id="something">
  <AnyComponent />
</HashAnchor>

I can't use ref here because I can't know for sure that its child is going to be a DOM node; it might be a component. That's where findDOMNode comes in handy: it will find the underlying DOM node no matter what the child is.

I think this is exactly the case where "findDOMNode escape hatch" use is justified.

One still could argue that findDOMNode is an antipattern even in this case, because ideally we would want to add an id attribute to the underlying dom node in order to conform to the browser's native anchor behavior.

So we can just wrap the child with a <div id="something" />:

I would use it like this:

<HashAnchor id="something">
  <div id="something">
    <AnyComponent />
  </div>
</HashAnchor>

@bskimball
Copy link

this.element is a ref to a dom node. I was using findDomNode to get the bounding coordinates of a dom node.

@everdimension
Copy link

everdimension commented Mar 14, 2017

@bskimball if this.element is already a dom node then all you need is this.element.getClientBoundingRect()
You don't need .findDOMNode

You need findDOMNode only when all you have is a reference to a component instance.

@bskimball
Copy link

I'm sorry I misrepresented this.element it is a component instance.

@Deraen
Copy link
Member

Deraen commented Mar 14, 2017

@everdimension AFAIK Most React components support ref so you should be able to use <AnyComponent ref="ref-fn"/> (or [AnyComponent {:ref ref-fn}]).

@everdimension
Copy link

@Deraen not "most", but "stateful" components support refs, but the ref callback function doesn't give you a dom node; it gives you a component instance.

@Deraen
Copy link
Member

Deraen commented Nov 28, 2017

Tagging as wontfix, as this doesn't seem to be needed in near future. The function is still available and not deprecated in React 16.

If we at some point change Reagent to generate functional components, we would need to revisit this as findDOMNode doesn't work for those. But that would be a lot work anyway.

@Deraen
Copy link
Member

Deraen commented Apr 19, 2020

Related #490

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants