Semantic-ui-react: Portal: rework #handleRef to avoid using ReactDOM.findDOMNode

Created on 24 May 2017  ยท  2Comments  ยท  Source: Semantic-Org/Semantic-UI-React

Relevant line: https://github.com/Semantic-Org/Semantic-UI-React/blob/master/src/addons/Portal/Portal.js#L417

ReactDOM.findDOMNode breaks ReactTestRenderer, and it will never be supported.

Additionally, even React documentation warns against using #findDOMNode.

Maybe each component could have a property nodeRef or similar that holds the DOM element? Then Portal could check to see if its ref is a ReactComponent or a ReactElement? The main downside is that custom components would need to add a nodeRef, which would be Semver Major.

Aside from actually solving the problem, my current workaround to keep Jest tests working is to add this to the top of the test:

jest.mock('react-dom', () => {
  return {
    findDOMNode: jest.fn(() => {})
  }
})

It might be useful to document this for people that do want to use Jest snapshot tests.

Steps

Add any Semantic UI component that uses Portal and try to use Jest snapshot testing.

Expected Result

Snapshot should be created and tests work as planned.

Actual Result

 FAIL  tests/app.jsx (6.945s)
  โ— should check default app structure

    Invariant Violation: getNodeFromInstance: Invalid argument.

      at invariant (node_modules/fbjs/lib/invariant.js:44:15)
      at Object.getNodeFromInstance (node_modules/react-dom/lib/ReactDOMComponentTree.js:162:77)
      at Object.findDOMNode (node_modules/react-dom/lib/findDOMNode.js:49:41)
      at Portal._this.handleRef (node_modules/semantic-ui-react/dist/commonjs/addons/Portal/Portal.js:276:52)
      at attachRef (node_modules/react-test-renderer/lib/ReactRef.js:20:5)
      at Object.<anonymous>.ReactRef.attachRefs (node_modules/react-test-renderer/lib/ReactRef.js:42:5)
      at ReactCompositeComponentWrapper.attachRefs (node_modules/react-test-renderer/lib/ReactReconciler.js:23:12)
      at CallbackQueue.notifyAll (node_modules/react-test-renderer/lib/CallbackQueue.js:76:22)
      at ReactTestReconcileTransaction.close (node_modules/react-test-renderer/lib/ReactTestReconcileTransaction.js:36:26)
      at ReactTestReconcileTransaction.closeAll (node_modules/react-test-renderer/lib/Transaction.js:206:25)
      at ReactTestReconcileTransaction.perform (node_modules/react-test-renderer/lib/Transaction.js:153:16)
      at batchedMountComponentIntoNode (node_modules/react-test-renderer/lib/ReactTestMount.js:69:27)
      at ReactDefaultBatchingStrategyTransaction.perform (node_modules/react-test-renderer/lib/Transaction.js:140:20)
      at Object.batchedUpdates (node_modules/react-test-renderer/lib/ReactDefaultBatchingStrategy.js:62:26)
      at Object.batchedUpdates (node_modules/react-test-renderer/lib/ReactUpdates.js:97:27)
      at Object.render (node_modules/react-test-renderer/lib/ReactTestMount.js:125:18)
      at Object.<anonymous> (tests/app.jsx:15:41)
      at Promise.resolve.then.el (node_modules/p-map/index.js:42:16)
      at process._tickCallback (internal/process/next_tick.js:109:7)

Version

v0.68.3

help wanted needs engineering

Most helpful comment

Ideally, we'd remove findDOMNode usage entirely. My reasoning and proposed replacement are expressed here.

All 2 comments

Ideally, we'd remove findDOMNode usage entirely. My reasoning and proposed replacement are expressed here.

Portal now uses Ref to handle refs, see #2219. There is still findDOMNode under hood, but we can't get of it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jayphelps picture jayphelps  ยท  3Comments

SajagTiwari picture SajagTiwari  ยท  3Comments

saikrishnadeep picture saikrishnadeep  ยท  3Comments

keeslinp picture keeslinp  ยท  3Comments

GautierT picture GautierT  ยท  3Comments