From a0967a151cadb17e95e548c57a1528625f8253ee Mon Sep 17 00:00:00 2001 From: Oleksandr Fediashov Date: Tue, 8 Sep 2020 16:26:20 +0200 Subject: [PATCH] fix(Transition): schedule changes only on `status` change --- src/modules/Transition/Transition.js | 15 ++++++------- .../modules/Transition/Transition-test.js | 21 +++++++++++++++++++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/modules/Transition/Transition.js b/src/modules/Transition/Transition.js index 015624eaf6..0cd0fb8e09 100644 --- a/src/modules/Transition/Transition.js +++ b/src/modules/Transition/Transition.js @@ -87,16 +87,17 @@ export default class Transition extends Component { const durationType = TRANSITION_CALLBACK_TYPE[nextStatus] const durationValue = normalizeTransitionDuration(duration, durationType) - clearTimeout(this.timeoutId) - this.timeoutId = setTimeout( - () => this.setState((state) => ({ status: state.nextStatus })), - durationValue, - ) + this.timeoutId = setTimeout(() => this.setState({ status: nextStatus }), durationValue) } updateStatus = (prevState) => { - if (this.state.status !== this.state.nextStatus && this.state.nextStatus) { - this.handleStart(this.state.nextStatus) + if (prevState.status !== this.state.status) { + // Timeout should be cleared in any case as previous can lead set to unexpected `nextStatus` + clearTimeout(this.timeoutId) + + if (this.state.nextStatus) { + this.handleStart(this.state.nextStatus) + } } if (!prevState.animating && this.state.animating) { diff --git a/test/specs/modules/Transition/Transition-test.js b/test/specs/modules/Transition/Transition-test.js index ac3b932a6e..258cc6bc15 100644 --- a/test/specs/modules/Transition/Transition-test.js +++ b/test/specs/modules/Transition/Transition-test.js @@ -419,6 +419,27 @@ describe('Transition', () => { , ) }) + + it('is called after a render with visibility changes', (done) => { + // This test ensures that a setTimeout will not be cleared on a simple rerender + // https://github.com/Semantic-Org/Semantic-UI-React/issues/4059 + + const onComplete = sandbox.spy() + + wrapperMount( + +

+ , + ) + + setTimeout(() => { + wrapper.setProps({}) + }, 100) + setTimeout(() => { + onComplete.should.have.been.calledOnce() + done() + }, 250) + }) }) describe('onHide', () => {