Skip to content

Commit dffec89

Browse files
committed
feat(Transition): Add findDOMNode prop
Useful for strict mode compatibility.
1 parent 2eb45b2 commit dffec89

File tree

3 files changed

+60
-2
lines changed

3 files changed

+60
-2
lines changed

src/ReplaceTransition.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class ReplaceTransition extends React.Component {
2828
const child = React.Children.toArray(children)[idx];
2929

3030
if (child.props[handler]) child.props[handler](...originalArgs)
31-
if (this.props[handler]) this.props[handler](findDOMNode(this))
31+
if (this.props[handler]) this.props[handler](this.props.findDOMNode(this))
3232
}
3333

3434
render() {
@@ -39,6 +39,7 @@ class ReplaceTransition extends React.Component {
3939
} = this.props;
4040
const [first, second] = React.Children.toArray(children);
4141

42+
delete props.findDOMNode;
4243
delete props.onEnter;
4344
delete props.onEntering;
4445
delete props.onEntered;
@@ -76,6 +77,11 @@ ReplaceTransition.propTypes = {
7677

7778
return null;
7879
},
80+
findDOMNode: PropTypes.func,
7981
};
8082

83+
ReplaceTransition.defaultProps = {
84+
findDOMNode,
85+
}
86+
8187
export default ReplaceTransition;

src/Transition.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ class Transition extends React.Component {
216216
if (nextStatus !== null) {
217217
// nextStatus will always be ENTERING or EXITING.
218218
this.cancelNextCallback()
219-
const node = ReactDOM.findDOMNode(this)
219+
const node = this.props.findDOMNode(this);
220220

221221
if (nextStatus === ENTERING) {
222222
this.performEnter(node, mounting)
@@ -348,6 +348,7 @@ class Transition extends React.Component {
348348
delete childProps.appear
349349
delete childProps.enter
350350
delete childProps.exit
351+
delete childProps.findDOMNode;
351352
delete childProps.timeout
352353
delete childProps.addEndListener
353354
delete childProps.onEnter
@@ -424,6 +425,14 @@ Transition.propTypes = {
424425
*/
425426
exit: PropTypes.bool,
426427

428+
/**
429+
* The function to find the rendered DOM node that is passed to the transition callbacks.
430+
*
431+
* By default ReactDOM.findDOMNode is used. For `React.StrictMode` compatiblity
432+
* another function must be provided.
433+
*/
434+
findDOMNode: PropTypes.func,
435+
427436
/**
428437
* The duration of the transition, in milliseconds.
429438
* Required unless `addEndListener` is provided.
@@ -526,6 +535,7 @@ Transition.defaultProps = {
526535
appear: false,
527536
enter: true,
528537
exit: true,
538+
findDOMNode: ReactDOM.findDOMNode,
529539

530540
onEnter: noop,
531541
onEntering: noop,

test/Transition-test.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,4 +469,46 @@ describe('Transition', () => {
469469
wrapper.setState({ in: false })
470470
})
471471
})
472+
473+
describe('findDOMNode', () => {
474+
it('can receive a custom findDOMNode method', done => {
475+
class StrictModeTransition extends React.Component {
476+
constructor(props) {
477+
super(props);
478+
this.childRef = React.createRef();
479+
this.findDOMNode = this.findDOMNode.bind(this);
480+
}
481+
482+
findDOMNode() {
483+
return this.childRef.current;
484+
}
485+
486+
render() {
487+
return (
488+
<Transition findDOMNode={this.findDOMNode} {...this.props}>
489+
{status => <div><span ref={this.childRef}>{status}</span></div>}
490+
</Transition>
491+
);
492+
}
493+
}
494+
495+
const expectSpan = sinon.spy(node => expect(node.nodeName).toEqual('SPAN'));
496+
const handleExited = () => {
497+
expect(expectSpan.called).toBe(true);
498+
499+
done();
500+
}
501+
502+
const wrapper = mount(
503+
<StrictModeTransition
504+
in
505+
timeout={10}
506+
onExiting={expectSpan}
507+
onExited={handleExited}
508+
/>
509+
);
510+
511+
wrapper.setProps({ in: false });
512+
})
513+
})
472514
})

0 commit comments

Comments
 (0)