From 3a4cf9c91ab5f25caaa9501b129bce66ec9bb56b Mon Sep 17 00:00:00 2001 From: Nikita Nafranets Date: Tue, 5 Mar 2019 16:59:59 +0300 Subject: [PATCH] Make exit timeout optional (#464) * fix bug from issue #460 * Update src/Transition.js Co-Authored-By: dimensi * fix grammar and remove required from exit, enter props * rewrite test * little update --- src/Transition.js | 25 +++++++++++++++---------- test/Transition-test.js | 24 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/Transition.js b/src/Transition.js index a9133cc2..8ae11270 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 doesNotHaveTimeoutOrListener = timeout == null && !this.props.addEndListener + if (!node || doesNotHaveTimeoutOrListener) { 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/test/Transition-test.js b/test/Transition-test.js index 380eb147..d021370c 100644 --- a/test/Transition-test.js +++ b/test/Transition-test.js @@ -131,6 +131,30 @@ 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) { + return done() + } + throw new Error('wrong timeout') + } + }) + }) + describe('appearing timeout', () => { it('should use enter timeout if appear not set', done => { let calledBeforeEntered = false