diff --git a/src/Async.js b/src/Async.js index b19df77f1f..2d9fc7d7ae 100644 --- a/src/Async.js +++ b/src/Async.js @@ -88,6 +88,8 @@ export default class Async extends Component { cache && Object.prototype.hasOwnProperty.call(cache, inputValue) ) { + this._callback = null; + this.setState({ options: cache[inputValue] }); @@ -96,14 +98,14 @@ export default class Async extends Component { } const callback = (error, data) => { - if (callback === this._callback) { - this._callback = null; + const options = data && data.options || []; - const options = data && data.options || []; + if (cache) { + cache[inputValue] = options; + } - if (cache) { - cache[inputValue] = options; - } + if (callback === this._callback) { + this._callback = null; this.setState({ isLoading: false, diff --git a/test/Async-test.js b/test/Async-test.js index 3e76e9fc15..4c28d1395d 100644 --- a/test/Async-test.js +++ b/test/Async-test.js @@ -146,6 +146,34 @@ describe('Async', () => { return expect(asyncNode.textContent, 'to contain', 'Loading'); }); + // TODO: I'm not sure what the best way to test this is, because this test returns positive even + // before the change. However, manual testing by throttling the network with Chrome devtools shows + // that this fixes the issue. + it.skip('caches the result of all option fetches', () => { + const optionResponse = createOptionsResponse(['foo']); + function loadOptions (input, resolve) { + setTimeout(function() { + resolve(null, optionResponse); + }, 10 - input.length); + // resolve(null, optionResponse); + } + createControl({ + loadOptions, + }); + const instance = asyncInstance; + typeSearchText('t'); + typeSearchText('te'); + typeSearchText('tes'); + + // TODO: How to test this? + setTimeout(function() { + console.log(instance._cache); + expect(instance._cache.t, 'to equal', optionResponse.options); + expect(instance._cache.te, 'to equal', optionResponse.options); + expect(instance._cache.tes, 'to equal', optionResponse.options); + }, 30); + }); + describe('with callbacks', () => { it('should display the loaded options', () => { function loadOptions (input, resolve) {