diff --git a/lib/Autocomplete.js b/lib/Autocomplete.js index 8b56cb7f..df884e08 100644 --- a/lib/Autocomplete.js +++ b/lib/Autocomplete.js @@ -62,8 +62,17 @@ let Autocomplete = React.createClass({ this._performAutoCompleteOnKeyUp = false }, - componentWillReceiveProps () { + componentWillReceiveProps (nextProps) { this._performAutoCompleteOnUpdate = true + // If `items` has changed we want to reset `highlightedIndex` + // since it probably no longer refers to a relevant item + if (this.props.items !== nextProps.items || + // The entries in `items` may have been changed even though the + // object reference remains the same, double check by seeing + // if `highlightedIndex` points to an existing item + this.state.highlightedIndex >= nextProps.items.length) { + this.setState({ highlightedIndex: null }) + } }, componentDidUpdate (prevProps, prevState) { diff --git a/lib/__tests__/Autocomplete-test.js b/lib/__tests__/Autocomplete-test.js index 165f37b8..c60d9a15 100644 --- a/lib/__tests__/Autocomplete-test.js +++ b/lib/__tests__/Autocomplete-test.js @@ -60,6 +60,21 @@ describe('Autocomplete acceptance tests', () => { }); + it('should reset `highlightedIndex` when `items` changes', () => { + autocompleteWrapper.setState({ highlightedIndex: 10 }); + autocompleteWrapper.setProps({ items: [] }); + expect(autocompleteWrapper.state('highlightedIndex')).toBe(null); + }); + + it('should reset `highlightedIndex` when it falls outside of possible `items` range', () => { + const items = getStates(); + autocompleteWrapper.setProps({ items }); + autocompleteWrapper.setState({ highlightedIndex: 10 }); + items.length = 5; + autocompleteWrapper.setProps({ items }); + expect(autocompleteWrapper.state('highlightedIndex')).toBe(null); + }); + }); // Event handler unit tests