Refactor default value logic into utility hook.
Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { ChangeEvent, useEffect, useState } from 'react';
|
||||
import React, { ChangeEvent, useState } from 'react';
|
||||
import { Chip, TextField } from '@material-ui/core';
|
||||
import {
|
||||
Autocomplete,
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
AutocompleteRenderInputParams,
|
||||
} from '@material-ui/lab';
|
||||
import { useSearch } from '../SearchContext';
|
||||
import { useAsyncFilterValues } from './hooks';
|
||||
import { useAsyncFilterValues, useDefaultFilterValue } from './hooks';
|
||||
import { SearchFilterComponentProps } from './SearchFilter';
|
||||
|
||||
/**
|
||||
@@ -46,6 +46,7 @@ export const AutocompleteFilter = (props: SearchAutocompleteFilterProps) => {
|
||||
limitTags,
|
||||
} = props;
|
||||
const [inputValue, setInputValue] = useState<string>('');
|
||||
useDefaultFilterValue(name, defaultValue);
|
||||
const { value: values, loading } = useAsyncFilterValues(
|
||||
asyncValues,
|
||||
inputValue,
|
||||
@@ -56,20 +57,6 @@ export const AutocompleteFilter = (props: SearchAutocompleteFilterProps) => {
|
||||
const filterValue =
|
||||
(filters[name] as string | string[] | undefined) || (multiple ? [] : null);
|
||||
|
||||
useEffect(() => {
|
||||
const defaultIsEmpty = !defaultValue;
|
||||
const defaultIsEmptyArray =
|
||||
Array.isArray(defaultValue) && defaultValue.length === 0;
|
||||
|
||||
if (!defaultIsEmpty && !defaultIsEmptyArray) {
|
||||
setFilters(prevFilters => ({
|
||||
...prevFilters,
|
||||
[name]: defaultValue,
|
||||
}));
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
// Set new filter values on input change.
|
||||
const handleChange = (
|
||||
_: ChangeEvent<{}>,
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { ReactElement, ChangeEvent, useEffect } from 'react';
|
||||
import React, { ReactElement, ChangeEvent } from 'react';
|
||||
import {
|
||||
makeStyles,
|
||||
FormControl,
|
||||
@@ -31,7 +31,7 @@ import {
|
||||
SearchAutocompleteFilterProps,
|
||||
} from './SearchFilter.Autocomplete';
|
||||
import { useSearch } from '../SearchContext';
|
||||
import { useAsyncFilterValues } from './hooks';
|
||||
import { useAsyncFilterValues, useDefaultFilterValue } from './hooks';
|
||||
|
||||
const useStyles = makeStyles({
|
||||
label: {
|
||||
@@ -64,16 +64,7 @@ const CheckboxFilter = (props: SearchFilterComponentProps) => {
|
||||
const { className, defaultValue, label, name, values = [] } = props;
|
||||
const classes = useStyles();
|
||||
const { filters, setFilters } = useSearch();
|
||||
|
||||
useEffect(() => {
|
||||
if (Array.isArray(defaultValue)) {
|
||||
setFilters(prevFilters => ({
|
||||
...prevFilters,
|
||||
[name]: defaultValue,
|
||||
}));
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
useDefaultFilterValue(name, defaultValue);
|
||||
|
||||
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
const {
|
||||
@@ -127,6 +118,7 @@ const SelectFilter = (props: SearchFilterComponentProps) => {
|
||||
values: givenValues,
|
||||
} = props;
|
||||
const classes = useStyles();
|
||||
useDefaultFilterValue(name, defaultValue);
|
||||
const { value: values = [], loading } = useAsyncFilterValues(
|
||||
asyncValues,
|
||||
'',
|
||||
@@ -135,16 +127,6 @@ const SelectFilter = (props: SearchFilterComponentProps) => {
|
||||
);
|
||||
const { filters, setFilters } = useSearch();
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof defaultValue === 'string') {
|
||||
setFilters(prevFilters => ({
|
||||
...prevFilters,
|
||||
[name]: defaultValue,
|
||||
}));
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const handleChange = (e: ChangeEvent<{ value: unknown }>) => {
|
||||
const {
|
||||
target: { value },
|
||||
|
||||
@@ -14,9 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useRef } from 'react';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import useAsyncFn from 'react-use/lib/useAsyncFn';
|
||||
import useDebounce from 'react-use/lib/useDebounce';
|
||||
import { useSearch } from '../SearchContext';
|
||||
|
||||
/**
|
||||
* Utility hook for either asynchronously loading filter values from a given
|
||||
@@ -68,3 +69,27 @@ export const useAsyncFilterValues = (
|
||||
|
||||
return state;
|
||||
};
|
||||
|
||||
/**
|
||||
* Utility hook for applying a given default value to the search context.
|
||||
*/
|
||||
export const useDefaultFilterValue = (
|
||||
name: string,
|
||||
defaultValue?: string | string[] | null,
|
||||
) => {
|
||||
const { setFilters } = useSearch();
|
||||
|
||||
useEffect(() => {
|
||||
const defaultIsEmpty = !defaultValue;
|
||||
const defaultIsEmptyArray =
|
||||
Array.isArray(defaultValue) && defaultValue.length === 0;
|
||||
|
||||
if (!defaultIsEmpty && !defaultIsEmptyArray) {
|
||||
setFilters(prevFilters => ({
|
||||
...prevFilters,
|
||||
[name]: defaultValue,
|
||||
}));
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user