diff --git a/CHANGELOG.md b/CHANGELOG.md index 907e3ba438..64ab900794 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ This project adheres to [Semantic Versioning](https://semver.org/). - [#2292](https://github.com/plotly/dash/pull/2292) Pages: find the 404 page even if `pages_folder` is nested, or the 404 page is nested inside `pages_folder`. - [#2265](https://github.com/plotly/dash/pull/2265) Removed deprecated `before_first_request` as reported in [#2177](https://github.com/plotly/dash/issues/2177). - [#2257](https://github.com/plotly/dash/pull/2257) Fix tuple types in the TypeScript component generator. +- [#2293](https://github.com/plotly/dash/pull/2293) Fix Dropdown useMemo not detecting equal objects ### Changed diff --git a/components/dash-core-components/package-lock.json b/components/dash-core-components/package-lock.json index 0811e76b3d..b2a07a3b6b 100644 --- a/components/dash-core-components/package-lock.json +++ b/components/dash-core-components/package-lock.json @@ -30,6 +30,7 @@ "react-dates": "^21.8.0", "react-docgen": "^5.4.3", "react-dropzone": "^4.1.2", + "react-fast-compare": "^3.2.0", "react-markdown": "^4.3.1", "react-resize-detector": "^6.7.6", "react-select-fast-filter-options": "^0.2.3", @@ -7049,6 +7050,11 @@ "react": ">=0.14.0" } }, + "node_modules/react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" + }, "node_modules/react-input-autosize": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-2.2.2.tgz", @@ -14302,6 +14308,11 @@ "prop-types": "^15.5.7" } }, + "react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" + }, "react-input-autosize": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-2.2.2.tgz", diff --git a/components/dash-core-components/package.json b/components/dash-core-components/package.json index 578f7f952a..812c2c82a7 100644 --- a/components/dash-core-components/package.json +++ b/components/dash-core-components/package.json @@ -57,6 +57,7 @@ "react-dates": "^21.8.0", "react-docgen": "^5.4.3", "react-dropzone": "^4.1.2", + "react-fast-compare": "^3.2.0", "react-markdown": "^4.3.1", "react-resize-detector": "^6.7.6", "react-select-fast-filter-options": "^0.2.3", diff --git a/components/dash-core-components/src/fragments/Dropdown.react.js b/components/dash-core-components/src/fragments/Dropdown.react.js index 8da5d0bd78..1812f6fa1f 100644 --- a/components/dash-core-components/src/fragments/Dropdown.react.js +++ b/components/dash-core-components/src/fragments/Dropdown.react.js @@ -1,5 +1,5 @@ import {isNil, pluck, without, pick} from 'ramda'; -import React, {useState, useCallback, useEffect, useMemo} from 'react'; +import React, {useState, useCallback, useEffect, useMemo, useRef} from 'react'; import ReactDropdown from 'react-virtualized-select'; import createFilterOptions from 'react-select-fast-filter-options'; import '../components/css/react-virtualized-select@3.1.0.css'; @@ -8,6 +8,7 @@ import '../components/css/Dropdown.css'; import {propTypes, defaultProps} from '../components/Dropdown.react'; import {sanitizeOptions} from '../utils/optionTypes'; +import isEqual from 'react-fast-compare'; // Custom tokenizer, see https://github.com/bvaughn/js-search/issues/43 // Split on spaces @@ -47,6 +48,12 @@ const Dropdown = props => { value, } = props; const [optionsCheck, setOptionsCheck] = useState(null); + const persistentOptions = useRef(null); + + if (!persistentOptions || !isEqual(options, persistentOptions.current)) { + persistentOptions.current = options; + } + const [sanitizedOptions, filterOptions] = useMemo(() => { let sanitized = sanitizeOptions(options); @@ -83,7 +90,7 @@ const Dropdown = props => { indexes, }), ]; - }, [options]); + }, [persistentOptions.current]); const onChange = useCallback( selectedOption => { @@ -146,7 +153,7 @@ const Dropdown = props => { >