From 75602cae03189be16b17082beae68094e511eb97 Mon Sep 17 00:00:00 2001 From: Youcef Mammar Date: Tue, 26 Nov 2019 14:09:32 +0100 Subject: [PATCH] fix(queryHook): restore behaviour of queryHook (#4202) * fix(queryHook): restore behaviour of queryHook There has been many complaints from user on our [debouncing guide](https://www.algolia.com/doc/guides/building-search-ui/going-further/improve-performance/js/#debouncing) no longer working as expected. This issue was introduced when the SearchBox component was converted into a Preact, and the following condition removed: https://github.com/algolia/instantsearch.js/commit/c073a9acb51fff3c15278fcd563e47fec55c8365#diff-530222e0c4597f2110dc6ba173a306b0L98 **Before SearchBox refactor**: - when input was focused, the query exposed by the connector didn't update the input value - when input was not focused, the query exposed by the connector did update the input value **After SearchBox refactor**: - regardless on whether input was focused, the query exposed by the connector updates the input value This PR restores the logic as found before the refactor. fixes https://github.com/algolia/instantsearch.js/issues/4141 * chore: update snapshots * fix: reset works again * add a comment explaining the bahviour of the widget on focus * add variable names to comment * chore: update e2e tests * add comment explaining test puropose --- package.json | 2 +- .../__snapshots__/RefinementList-test.js.snap | 4 + src/components/SearchBox/SearchBox.js | 45 +++-- .../SearchBox/__tests__/SearchBox-test.js | 181 +++++++++++++----- .../__snapshots__/SearchBox-test.js.snap | 4 + stories/search-box.stories.js | 17 ++ yarn.lock | 6 +- 7 files changed, 198 insertions(+), 61 deletions(-) diff --git a/package.json b/package.json index 9a4561380d4..992545b720e 100644 --- a/package.json +++ b/package.json @@ -113,7 +113,7 @@ "eslint-plugin-react": "7.16.0", "eslint-plugin-react-hooks": "2.3.0", "inquirer": "6.5.2", - "instantsearch-e2e-tests": "algolia/instantsearch-e2e-tests#v1.2.3", + "instantsearch-e2e-tests": "algolia/instantsearch-e2e-tests#1.2.4", "jest": "24.9.0", "jest-diff": "24.9.0", "jest-environment-jsdom": "24.9.0", diff --git a/src/components/RefinementList/__tests__/__snapshots__/RefinementList-test.js.snap b/src/components/RefinementList/__tests__/__snapshots__/RefinementList-test.js.snap index 9ea488dd79f..6055a92d297 100644 --- a/src/components/RefinementList/__tests__/__snapshots__/RefinementList-test.js.snap +++ b/src/components/RefinementList/__tests__/__snapshots__/RefinementList-test.js.snap @@ -381,6 +381,8 @@ Array [ className="input" disabled={false} maxLength={512} + onBlur={[Function]} + onFocus={[Function]} onInput={[Function]} placeholder="Search" spellCheck={false} @@ -568,6 +570,8 @@ Array [ className="input" disabled={false} maxLength={512} + onBlur={[Function]} + onFocus={[Function]} onInput={[Function]} placeholder="Search" spellCheck={false} diff --git a/src/components/SearchBox/SearchBox.js b/src/components/SearchBox/SearchBox.js index 1a75b201783..44e80b3cafb 100644 --- a/src/components/SearchBox/SearchBox.js +++ b/src/components/SearchBox/SearchBox.js @@ -52,7 +52,8 @@ class SearchBox extends Component { }; state = { - query: this.props.searchAsYouType ? '' : this.props.query, + query: this.props.query, + focused: false, }; /** @@ -72,13 +73,23 @@ class SearchBox extends Component { if (searchAsYouType) { refine(query); - } else { - this.setState({ query }); } + this.setState({ query }); onChange(event); }; + componentWillReceiveProps(nextProps) { + /** + * when the user is typing, we don't want to replace the query typed + * by the user (state.query) with the query exposed by the connector (props.query) + * see: https://github.com/algolia/instantsearch.js/issues/4141 + */ + if (!this.state.focused && nextProps.query !== this.state.query) { + this.setState({ query: nextProps.query }); + } + } + onSubmit = event => { const { searchAsYouType, refine, onSubmit } = this.props; @@ -96,20 +107,25 @@ class SearchBox extends Component { }; onReset = event => { - const { searchAsYouType, refine, onReset } = this.props; + const { refine, onReset } = this.props; const query = ''; this.input.focus(); refine(query); - - if (!searchAsYouType) { - this.setState({ query }); - } + this.setState({ query }); onReset(event); }; + onBlur = () => { + this.setState({ focused: false }); + }; + + onFocus = () => { + this.setState({ focused: true }); + }; + render() { const { cssClasses, @@ -120,11 +136,8 @@ class SearchBox extends Component { showLoadingIndicator, templates, isSearchStalled, - searchAsYouType, } = this.props; - const query = searchAsYouType ? this.props.query : this.state.query; - return (
(this.input = inputRef)} - value={query} + value={this.state.query} disabled={this.props.disabled} className={cssClasses.input} type="search" @@ -149,6 +162,8 @@ class SearchBox extends Component { spellCheck={false} maxLength={512} onInput={this.onInput} + onBlur={this.onBlur} + onFocus={this.onFocus} />