diff --git a/src/ReplaceTransition.js b/src/ReplaceTransition.js
index c1081c59..b80362f4 100644
--- a/src/ReplaceTransition.js
+++ b/src/ReplaceTransition.js
@@ -28,7 +28,7 @@ class ReplaceTransition extends React.Component {
const child = React.Children.toArray(children)[idx];
if (child.props[handler]) child.props[handler](...originalArgs)
- if (this.props[handler]) this.props[handler](findDOMNode(this))
+ if (this.props[handler]) this.props[handler](this.props.findDOMNode(this))
}
render() {
@@ -39,6 +39,7 @@ class ReplaceTransition extends React.Component {
} = this.props;
const [first, second] = React.Children.toArray(children);
+ delete props.findDOMNode;
delete props.onEnter;
delete props.onEntering;
delete props.onEntered;
@@ -76,6 +77,11 @@ ReplaceTransition.propTypes = {
return null;
},
+ findDOMNode: PropTypes.func,
};
+ReplaceTransition.defaultProps = {
+ findDOMNode,
+}
+
export default ReplaceTransition;
diff --git a/src/Transition.js b/src/Transition.js
index a12cf71f..eeea4f9d 100644
--- a/src/Transition.js
+++ b/src/Transition.js
@@ -209,7 +209,7 @@ class Transition extends React.Component {
if (nextStatus !== null) {
// nextStatus will always be ENTERING or EXITING.
this.cancelNextCallback()
- const node = ReactDOM.findDOMNode(this)
+ const node = this.props.findDOMNode(this);
if (nextStatus === ENTERING) {
this.performEnter(node, mounting)
@@ -341,6 +341,7 @@ class Transition extends React.Component {
delete childProps.appear
delete childProps.enter
delete childProps.exit
+ delete childProps.findDOMNode;
delete childProps.timeout
delete childProps.addEndListener
delete childProps.onEnter
@@ -427,6 +428,14 @@ Transition.propTypes = {
*/
exit: PropTypes.bool,
+ /**
+ * The function to find the rendered DOM node that is passed to the transition callbacks.
+ *
+ * By default ReactDOM.findDOMNode is used. For `React.StrictMode` compatiblity
+ * another function must be provided.
+ */
+ findDOMNode: PropTypes.func,
+
/**
* The duration of the transition, in milliseconds.
* Required unless `addEndListener` is provided.
@@ -529,6 +538,7 @@ Transition.defaultProps = {
appear: false,
enter: true,
exit: true,
+ findDOMNode: ReactDOM.findDOMNode,
onEnter: noop,
onEntering: noop,
diff --git a/test/Transition-test.js b/test/Transition-test.js
index 63d30c0e..f0adab77 100644
--- a/test/Transition-test.js
+++ b/test/Transition-test.js
@@ -469,4 +469,68 @@ describe('Transition', () => {
wrapper.setState({ in: false })
})
})
+
+ describe('findDOMNode', () => {
+ it('uses ReactDOM.findDOMNode by default', done => {
+ const expectDiv = jest.fn(node => expect(node.nodeName).toEqual('DIV'));
+ const handleExited = () => {
+ expect(expectDiv).toHaveBeenCalled()
+
+ done();
+ }
+
+ const wrapper = mount(
+
+ {status => {status}
}
+
+ );
+
+ wrapper.setProps({ in: false });
+ })
+
+ it('can receive a custom findDOMNode method', done => {
+ class StrictModeTransition extends React.Component {
+ constructor(props) {
+ super(props);
+ this.childRef = React.createRef();
+ this.findDOMNode = this.findDOMNode.bind(this);
+ }
+
+ findDOMNode() {
+ return this.childRef.current;
+ }
+
+ render() {
+ return (
+
+ {status => {status}
}
+
+ );
+ }
+ }
+
+ const expectSpan = jest.fn(node => expect(node.nodeName).toEqual('SPAN'));
+ const handleExited = () => {
+ expect(expectSpan).toHaveBeenCalled();
+
+ done();
+ }
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.setProps({ in: false });
+ })
+ })
})