react-dom-instance
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
We will only find instances from react's class components, functional components has no instances and
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:
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();
});
Here's the changelog
MIT Licensed