Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Transition): Add findDOMNode prop #457

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/ReplaceTransition.js
Expand Up @@ -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() {
Expand All @@ -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;
Expand Down Expand Up @@ -76,6 +77,11 @@ ReplaceTransition.propTypes = {

return null;
},
findDOMNode: PropTypes.func,
};

ReplaceTransition.defaultProps = {
findDOMNode,
}

export default ReplaceTransition;
12 changes: 11 additions & 1 deletion src/Transition.js
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -529,6 +538,7 @@ Transition.defaultProps = {
appear: false,
enter: true,
exit: true,
findDOMNode: ReactDOM.findDOMNode,

onEnter: noop,
onEntering: noop,
Expand Down
64 changes: 64 additions & 0 deletions test/Transition-test.js
Expand Up @@ -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(
<Transition
in
timeout={10}
onExiting={expectDiv}
onExited={handleExited}
>
{status => <div><span>{status}</span></div>}
</Transition>
);

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 (
<Transition findDOMNode={this.findDOMNode} {...this.props}>
{status => <div><span ref={this.childRef}>{status}</span></div>}
</Transition>
);
}
}

const expectSpan = jest.fn(node => expect(node.nodeName).toEqual('SPAN'));
const handleExited = () => {
expect(expectSpan).toHaveBeenCalled();

done();
}

const wrapper = mount(
<StrictModeTransition
in
timeout={10}
onExiting={expectSpan}
onExited={handleExited}
/>
);

wrapper.setProps({ in: false });
})
})
})