Skip to content

arqex/react-dom-instance

Repository files navigation

react-dom-instance

npm version CircleCI Codecov Coverage

When using react-dom's findDOMNode() we get the HTML node generated by a react component instance.

react-dom-instance's findInstance() goes in the opposite direction: from an HTML node, we get the react component instance that generated it.

Only React v16 and higher is supported

How it works

If we have some component like the following one:

import * as React from 'react';

class TestComponent extends React.Component {
  render(){
    return <div id="testNode" data-testid="testNode" />
  }
  sayHello(){
    console.log('Hello!');
  }
}

We can call the sayHello method getting the instance with react-dom-instance:

import { findInstance } from 'react-dom-instance';

const node = document.getElementById('testNode');
findInstance( node ).sayHello(); // 'Hello!' in the console

Installation

npm install react-dom-instance

API

findInstance( domNode, {options} )

Given the root domNode generated by a component, it returns the instance of the component. If can't find any instances linked to the domNode it returns false.

Functional components don't have instances, so using findInstance with one DOM node generated by them will also return false.

We can pass some options in order to retrieve the wanted instance from the DOM node:

Options

  • componentName

Sometimes there are more than one component instance linked to a DOM node. For example, when a component render method returns another component, or when using higher order components.

In those cases we can use componentName to tell findInstace what type of component instance we want:

// These 2 components will be linked to the same DOM node
class ParentComponet extends React.Component {
  render() { return <ChildComponent /> }
}

class ChildComponent extends React.Component {
  render() { return <div id="sharedNode" /> }
}

let domNode = document.getElementById('sharedNode');

// Get the instance of the `ParentComponent`
findInstance( domNode, {componentName: 'ParentComponent'} );

// By default, `findInstance` returns the instance of the leaf component
findInstance( domNode ); // ChildComponent instance
  • maxIteration

When there are more than one component linked to the same DOM node, findInstance navigates recursively through the react fibers looking for the instance of the right component we want. To make this process fast and avoid infinite loops there is a maximum number of iterations that the algorithm does until it decides that the instance can't be found. By default findInstance iterates 4 times looking for the instance and return false after not finding it.

If you have a DOM node with a lot of instances linked and know that more iterations are needed to find the one you want, you can pass maxIteration as an option with a bigger number:

findInstance( domNode, {componentName: 'MyComponent', maxIterations: 6} );

Usage with react testing library

This library was thought as a helper for testing with react testing library: sometimes it is useful to access to the component instances in order to create tests.

To make the integration easier, findInstance accepts the container returned by react testing library and know how to extract the instance linked to it:

import { render } from '@testing-library/react';
import { findInstance } from 'react-dom-instance';

it('should say hello', () => {
  // TestComponent from the first example in this readme
  const { container } = render( <TestComponent /> );

  findInstance( container ).sayHello();
});

We can also use the query methods to get instances from components down in the react tree:

it('should say hello', () => {
  // App component render TestComponent at some point
  const { queryByTestId } = render( <App /> );

  findInstance( queryByTestId('testNode') ).sayHello();
});

About

Get the react component instance from a DOM node

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published