Skip to content

Commit a01e213

Browse files
authored
feat: Add findDOMNode prop (#2)
* feat(Transition): Add findDOMNode prop Useful for strict mode compatibility. * test(Transition): Add test case for default findDOMNode * test(Transition): Use jest.fn instead of sinon
1 parent 61433b5 commit a01e213

File tree

3 files changed

+82
-2
lines changed

3 files changed

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

215215
if (nextStatus === ENTERING) {
216216
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: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,4 +469,68 @@ describe('Transition', () => {
469469
wrapper.setState({ in: false })
470470
})
471471
})
472+
473+
describe('findDOMNode', () => {
474+
it('uses ReactDOM.findDOMNode by default', done => {
475+
const expectDiv = jest.fn(node => expect(node.nodeName).toEqual('DIV'));
476+
const handleExited = () => {
477+
expect(expectDiv).toHaveBeenCalled()
478+
479+
done();
480+
}
481+
482+
const wrapper = mount(
483+
<Transition
484+
in
485+
timeout={10}
486+
onExiting={expectDiv}
487+
onExited={handleExited}
488+
>
489+
{status => <div><span>{status}</span></div>}
490+
</Transition>
491+
);
492+
493+
wrapper.setProps({ in: false });
494+
})
495+
496+
it('can receive a custom findDOMNode method', done => {
497+
class StrictModeTransition extends React.Component {
498+
constructor(props) {
499+
super(props);
500+
this.childRef = React.createRef();
501+
this.findDOMNode = this.findDOMNode.bind(this);
502+
}
503+
504+
findDOMNode() {
505+
return this.childRef.current;
506+
}
507+
508+
render() {
509+
return (
510+
<Transition findDOMNode={this.findDOMNode} {...this.props}>
511+
{status => <div><span ref={this.childRef}>{status}</span></div>}
512+
</Transition>
513+
);
514+
}
515+
}
516+
517+
const expectSpan = jest.fn(node => expect(node.nodeName).toEqual('SPAN'));
518+
const handleExited = () => {
519+
expect(expectSpan).toHaveBeenCalled();
520+
521+
done();
522+
}
523+
524+
const wrapper = mount(
525+
<StrictModeTransition
526+
in
527+
timeout={10}
528+
onExiting={expectSpan}
529+
onExited={handleExited}
530+
/>
531+
);
532+
533+
wrapper.setProps({ in: false });
534+
})
535+
})
472536
})

0 commit comments

Comments
 (0)