From 2c119efcd7be39fe729e442bbe21c79d6472ccf5 Mon Sep 17 00:00:00 2001 From: Nikita Nafranets Date: Fri, 1 Mar 2019 00:33:07 +0300 Subject: [PATCH 1/5] fix bug from issue #460 --- src/Transition.js | 25 ++++++++++++++---------- src/utils/PropTypes.js | 4 ++-- test/Transition-test.js | 43 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 12 deletions(-) diff --git a/src/Transition.js b/src/Transition.js index a9133cc2..f9f23be9 100644 --- a/src/Transition.js +++ b/src/Transition.js @@ -325,15 +325,18 @@ class Transition extends React.Component { onTransitionEnd(node, timeout, handler) { this.setNextCallback(handler) - if (node) { - if (this.props.addEndListener) { - this.props.addEndListener(node, this.nextCallback) - } - if (timeout != null) { - setTimeout(this.nextCallback, timeout) - } - } else { + const isNotHaveTimeoutOrListener = timeout == null && !this.props.addEndListener + if (!node || isNotHaveTimeoutOrListener) { setTimeout(this.nextCallback, 0) + return + } + + if (this.props.addEndListener) { + this.props.addEndListener(node, this.nextCallback) + } + + if (timeout != null) { + setTimeout(this.nextCallback, timeout) } } @@ -442,9 +445,11 @@ Transition.propTypes = { * }} * ``` * - * If the value of appear is not set, then the value from enter is taken. + * If the value of `appear` is not set, then the value from enter is taken. + * + * If the `enter` or `exit` value is `null` or `undefined`, then the timer is set to `0` * - * @type {number | { enter?: number, exit?: number }} + * @type {number | { enter: number, exit: number, appear?: number }} */ timeout: (props, ...args) => { let pt = timeoutsShape diff --git a/src/utils/PropTypes.js b/src/utils/PropTypes.js index 5e79556d..3d241f17 100644 --- a/src/utils/PropTypes.js +++ b/src/utils/PropTypes.js @@ -5,8 +5,8 @@ export const timeoutsShape = ? PropTypes.oneOfType([ PropTypes.number, PropTypes.shape({ - enter: PropTypes.number, - exit: PropTypes.number, + enter: PropTypes.number.isRequired, + exit: PropTypes.number.isRequired, appear: PropTypes.number, }).isRequired ]) diff --git a/test/Transition-test.js b/test/Transition-test.js index 380eb147..74abf6b7 100644 --- a/test/Transition-test.js +++ b/test/Transition-test.js @@ -438,5 +438,48 @@ describe('Transition', () => { wrapper.setState({ in: false }) }) + + + it('should unmount at once if not have enter timeout', done => { + const wrapper = mount( + { + expect(wrapper.getStatus()).toEqual(EXITED) + expect(ReactDOM.findDOMNode(wrapper)).toExist() + + done() + }} + /> + ).instance() + + expect(wrapper.getStatus()).toEqual(UNMOUNTED) + expect(ReactDOM.findDOMNode(wrapper)).toBeNull() + + wrapper.setState({ in: true }) + }) + + + it('should unmount at once if not have exit timeout', done => { + const wrapper = mount( + { + setTimeout(() => { + expect(wrapper.getStatus()).toEqual(UNMOUNTED) + expect(ReactDOM.findDOMNode(wrapper)).not.toExist() + done() + }) + }} + /> + ).instance() + + expect(wrapper.getStatus()).toEqual(ENTERED) + expect(ReactDOM.findDOMNode(wrapper)).toExist() + + wrapper.setState({ in: false }) + }) }) }) From e3db48b00c83c81615073cafe9a85f16346aac4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20Marohni=C4=87?= Date: Tue, 5 Mar 2019 16:31:22 +0300 Subject: [PATCH 2/5] Update src/Transition.js Co-Authored-By: dimensi --- src/Transition.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Transition.js b/src/Transition.js index f9f23be9..b2417577 100644 --- a/src/Transition.js +++ b/src/Transition.js @@ -325,7 +325,7 @@ class Transition extends React.Component { onTransitionEnd(node, timeout, handler) { this.setNextCallback(handler) - const isNotHaveTimeoutOrListener = timeout == null && !this.props.addEndListener + const doesNotHaveTimeoutOrListener = timeout == null && !this.props.addEndListener if (!node || isNotHaveTimeoutOrListener) { setTimeout(this.nextCallback, 0) return From bb8956f6773b72e7a7d1d8b0c7ada491afd97a7d Mon Sep 17 00:00:00 2001 From: Nikita Nafranets Date: Tue, 5 Mar 2019 16:34:31 +0300 Subject: [PATCH 3/5] fix grammar and remove required from exit, enter props --- src/Transition.js | 4 ++-- src/utils/PropTypes.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Transition.js b/src/Transition.js index b2417577..8ae11270 100644 --- a/src/Transition.js +++ b/src/Transition.js @@ -326,7 +326,7 @@ class Transition extends React.Component { this.setNextCallback(handler) const doesNotHaveTimeoutOrListener = timeout == null && !this.props.addEndListener - if (!node || isNotHaveTimeoutOrListener) { + if (!node || doesNotHaveTimeoutOrListener) { setTimeout(this.nextCallback, 0) return } @@ -449,7 +449,7 @@ Transition.propTypes = { * * If the `enter` or `exit` value is `null` or `undefined`, then the timer is set to `0` * - * @type {number | { enter: number, exit: number, appear?: number }} + * @type {number | { enter?: number, exit?: number, appear?: number }} */ timeout: (props, ...args) => { let pt = timeoutsShape diff --git a/src/utils/PropTypes.js b/src/utils/PropTypes.js index 3d241f17..5e79556d 100644 --- a/src/utils/PropTypes.js +++ b/src/utils/PropTypes.js @@ -5,8 +5,8 @@ export const timeoutsShape = ? PropTypes.oneOfType([ PropTypes.number, PropTypes.shape({ - enter: PropTypes.number.isRequired, - exit: PropTypes.number.isRequired, + enter: PropTypes.number, + exit: PropTypes.number, appear: PropTypes.number, }).isRequired ]) From 77309fba00d7e85db8df2e7ff34aeae2a540aab8 Mon Sep 17 00:00:00 2001 From: Nikita Nafranets Date: Tue, 5 Mar 2019 16:53:06 +0300 Subject: [PATCH 4/5] rewrite test --- test/Transition-test.js | 68 +++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 43 deletions(-) diff --git a/test/Transition-test.js b/test/Transition-test.js index 74abf6b7..4eaf7b44 100644 --- a/test/Transition-test.js +++ b/test/Transition-test.js @@ -131,6 +131,31 @@ describe('Transition', () => { inst.setProps({ in: true }) }) + it('should mount/unmount immediately if not have enter/exit timeout', (done) => { + const wrapper = mount( + +
+ + ) + + expect(wrapper.state('status')).toEqual(ENTERED) + let calledAfterTimeout = false + setTimeout(() => { + calledAfterTimeout = true + }, 10) + wrapper.setProps({ + in: false, + onExited() { + expect(wrapper.state('status')).toEqual(EXITED) + if (calledAfterTimeout) { + throw new Error('wrong timeout') + } else { + done() + } + } + }) + }) + describe('appearing timeout', () => { it('should use enter timeout if appear not set', done => { let calledBeforeEntered = false @@ -438,48 +463,5 @@ describe('Transition', () => { wrapper.setState({ in: false }) }) - - - it('should unmount at once if not have enter timeout', done => { - const wrapper = mount( - { - expect(wrapper.getStatus()).toEqual(EXITED) - expect(ReactDOM.findDOMNode(wrapper)).toExist() - - done() - }} - /> - ).instance() - - expect(wrapper.getStatus()).toEqual(UNMOUNTED) - expect(ReactDOM.findDOMNode(wrapper)).toBeNull() - - wrapper.setState({ in: true }) - }) - - - it('should unmount at once if not have exit timeout', done => { - const wrapper = mount( - { - setTimeout(() => { - expect(wrapper.getStatus()).toEqual(UNMOUNTED) - expect(ReactDOM.findDOMNode(wrapper)).not.toExist() - done() - }) - }} - /> - ).instance() - - expect(wrapper.getStatus()).toEqual(ENTERED) - expect(ReactDOM.findDOMNode(wrapper)).toExist() - - wrapper.setState({ in: false }) - }) }) }) From f0b8784386004237d471d96b59c0fade8cc577f2 Mon Sep 17 00:00:00 2001 From: Nikita Nafranets Date: Tue, 5 Mar 2019 16:56:04 +0300 Subject: [PATCH 5/5] little update --- test/Transition-test.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/Transition-test.js b/test/Transition-test.js index 4eaf7b44..d021370c 100644 --- a/test/Transition-test.js +++ b/test/Transition-test.js @@ -147,11 +147,10 @@ describe('Transition', () => { in: false, onExited() { expect(wrapper.state('status')).toEqual(EXITED) - if (calledAfterTimeout) { - throw new Error('wrong timeout') - } else { - done() + if (!calledAfterTimeout) { + return done() } + throw new Error('wrong timeout') } }) })