Skip to content

Commit 8c6ca7a

Browse files
committed
feat(Transition): Add findDOMNode prop
Useful for strict mode compatibility.
1 parent 0be6f7a commit 8c6ca7a

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
@@ -209,7 +209,7 @@ class Transition extends React.Component {
209209
if (nextStatus !== null) {
210210
// nextStatus will always be ENTERING or EXITING.
211211
this.cancelNextCallback()
212-
const node = ReactDOM.findDOMNode(this)
212+
const node = this.props.findDOMNode(this);
213213

214214
if (nextStatus === ENTERING) {
215215
this.performEnter(node, mounting)
@@ -341,6 +341,7 @@ class Transition extends React.Component {
341341
delete childProps.appear
342342
delete childProps.enter
343343
delete childProps.exit
344+
delete childProps.findDOMNode;
344345
delete childProps.timeout
345346
delete childProps.addEndListener
346347
delete childProps.onEnter
@@ -427,6 +428,14 @@ Transition.propTypes = {
427428
*/
428429
exit: PropTypes.bool,
429430

431+
/**
432+
* The function to find the rendered DOM node that is passed to the transition callbacks.
433+
*
434+
* By default ReactDOM.findDOMNode is used. For `React.StrictMode` compatiblity
435+
* another function must be provided.
436+
*/
437+
findDOMNode: PropTypes.func,
438+
430439
/**
431440
* The duration of the transition, in milliseconds.
432441
* Required unless `addEndListener` is provided.
@@ -529,6 +538,7 @@ Transition.defaultProps = {
529538
appear: false,
530539
enter: true,
531540
exit: true,
541+
findDOMNode: ReactDOM.findDOMNode,
532542

533543
onEnter: noop,
534544
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)