diff --git a/CHANGELOG.md b/CHANGELOG.md index aa5a508..8fc4e10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Release History +## 2.7.3 + - Fix race condition when `showLoading` is called right after `hideLoading` + ## 2.7.2 - Do not try to stop simulation if it hasn't begun diff --git a/build/loading_bar.js b/build/loading_bar.js index 7fb62d1..512a40f 100644 --- a/build/loading_bar.js +++ b/build/loading_bar.js @@ -95,7 +95,10 @@ var LoadingBar = exports.LoadingBar = function (_React$Component) { var endingAnimationTimeout = this.state.endingAnimationTimeout; - if (!progressInterval) { + var loadingBarNotShown = !progressInterval; + var endingAnimationGoing = percent === 100; + + if (loadingBarNotShown || endingAnimationGoing) { progressInterval = setInterval(this.boundSimulateProgress, this.props.updateTime); clearTimeout(endingAnimationTimeout); percent = 0; diff --git a/package.json b/package.json index 36befa2..ba65ed3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-redux-loading-bar", - "version": "2.7.2", + "version": "2.7.3", "description": "Simple Loading Bar for Redux and React", "main": "build/index.js", "typings": "index.d.ts", diff --git a/spec/loading_bar.js b/spec/loading_bar.js index 48efd61..3c594a8 100644 --- a/spec/loading_bar.js +++ b/spec/loading_bar.js @@ -256,7 +256,7 @@ describe('LoadingBar', () => { }) }) - describe('if it should be shown again during ending animation', () => { + describe('if showLoading is called during ending animation', () => { let spySimulateProgress beforeEach(() => { @@ -300,6 +300,45 @@ describe('LoadingBar', () => { expect(spySimulateProgress.calls.length).toEqual(3) }) }) + + describe('if showLoading is called right after hideLoading', () => { + let spySimulateProgress + + beforeEach(() => { + spySimulateProgress = spyOn( + LoadingBar.prototype, + 'simulateProgress', + ).andCallThrough() + }) + afterEach(() => { + spySimulateProgress.restore() + }) + + it('does not hides and resets the position', () => { + const wrapper = shallow() + + // Show Loading Bar + wrapper.setProps({ loading: 1 }) + clock.tick(UPDATE_TIME) + expect(wrapper.state().progressInterval).toExist() + + // Hiding loading bar should set percentage to 100 + wrapper.setProps({ loading: 0 }) + expect(wrapper.state().percent).toEqual(100) + + // Show Loading Bar again + wrapper.setProps({ loading: 1 }) + + // It should be shown + expect(wrapper.state().percent).toNotEqual(100) + + // Wait one tick to get the animation going + clock.tick(UPDATE_TIME) + + // The progress simulation is still going + expect(wrapper.state().progressInterval).toExist() + }) + }) }) describe('updateTime prop', () => { diff --git a/src/loading_bar.js b/src/loading_bar.js index c7569ee..d1778b7 100644 --- a/src/loading_bar.js +++ b/src/loading_bar.js @@ -57,7 +57,10 @@ export class LoadingBar extends React.Component { let { progressInterval, percent } = this.state const { endingAnimationTimeout } = this.state - if (!progressInterval) { + const loadingBarNotShown = !progressInterval + const endingAnimationGoing = percent === 100 + + if (loadingBarNotShown || endingAnimationGoing) { progressInterval = setInterval( this.boundSimulateProgress, this.props.updateTime,