Skip to content

Commit

Permalink
Merge pull request #9639 from marmelab/doc-setfilter-debounce
Browse files Browse the repository at this point in the history
[Doc] Add warning about using setFilters with other callbacks
  • Loading branch information
djhi authored Feb 5, 2024
2 parents cbee14c + 8ccf059 commit 4b825a0
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 3 deletions.
24 changes: 22 additions & 2 deletions docs/FilteringTutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -543,14 +543,14 @@ const PostFilterForm = () => {

const onSubmit = (values) => {
if (Object.keys(values).length > 0) {
setFilters(values);
setFilters(values, undefined, false);
} else {
hideFilter("main");
}
};

const resetFilter = () => {
setFilters({}, []);
setFilters({}, [], false);
};

return (
Expand Down Expand Up @@ -626,3 +626,23 @@ export const PostList = () => (
**Tip**: No need to pass any `filters` to the list anymore, as the `<PostFilterForm>` component will display them.

You can use a similar approach to offer alternative User Experiences for data filtering, e.g. to display the filters as a line in the datagrid headers.

## Using `setFilters` With Other List Context Methods

The `setFilters` method takes three arguments:

- `filters`: an object containing the new filter values
- `displayedFilters`: an object containing the new displayed filters
- `debounced`: set to false to disable the debounce (true by default)

So `setFilters` is debounced by default, to avoid making too many requests to the server when using search-as-you-type inputs.

When you use `setFilters` and other list context methods (like `setSort`) in a single function, you must disable the debounce. Otherwise, the `setFilters` call would override the other changes.

```jsx
const changeListParams = () => {
setSort({ field: 'name', order: 'ASC' });
// The 3rd parameter disables the debounce ⤵
setFilters({ is_published: true }, undefined, false);
};
```
2 changes: 1 addition & 1 deletion docs/List.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ export const PostList = () => (

## `children`

`<List>` itself doesn't render the list of records. It delegates this task to its children components. These children components grab the `data` from the `ListContext` and render them on screen.
`<List>` itself doesn't render the list of records. It delegates this task to its children components. These children components grab the `data` from the [`ListContext`](./useListContext.md) and render them on screen.

![List children](./img/list-children.webp)

Expand Down
54 changes: 54 additions & 0 deletions docs/useListContext.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,60 @@ export const Aside = () => (
);
```

## Using `setFilters` to Update Filters

The `setFilters` method is used to update the filters. It takes three arguments:

- `filters`: an object containing the new filter values
- `displayedFilters`: an object containing the new displayed filters
- `debounced`: set to false to disable the debounce (true by default)

You can use it to update the filters in a custom filter component:

```jsx
import { useState } from 'react';
import { useListContext } from 'react-admin';

const CustomFilter = () => {
const { filterValues, setFilters } = useListContext();
const [formValues, setFormValues] = useState(filterValues);

const handleChange = (event) => {
setFormValues(formValues => ({
...formValues,
[event.target.name]: event.target.value
}));
};

const handleSubmit = (event) => {
event.preventDefault();
// The 3rd parameter disables the debounce ⤵
setFilters(filterFormValues, undefined, false);
};

return (
<form onSubmit={handleSubmit}>
<input name="country" value={formValues.country} onChange={handleChange} />
<input name="city" value={formValues.city} onChange={handleChange} />
<input name="zipcode" value={formValues.zipcode} onChange={handleChange} />
<input type="submit">Filter</input>
</form>
);
};
```

Beware that `setFilters` is debounced by default, to avoid making too many requests to the server when using search-as-you-type inputs. In the example above, this is not necessary. That's why you should set the third argument to `setFilters` is set to `false` to disable the debounce.

Disabling the debounce with the third parameter is also necessary when you use `setFilters` and other list context methods (like `setSort`) in a single function. Otherwise, the `setFilters` call would override the other changes.

```jsx
const changeListParams = () => {
setSort({ field: 'name', order: 'ASC' });
// The 3rd parameter disables the debounce ⤵
setFilters({ is_published: true }, undefined, false);
};
```

## TypeScript

The `useListContext` hook accepts a generic parameter for the record type:
Expand Down
63 changes: 63 additions & 0 deletions docs/useListController.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,3 +253,66 @@ const {
refetch, // Callback for fetching the list data again
} = useListController();
```

## Using `setFilters` to Update Filters

The `setFilters` method is used to update the filters. It takes three arguments:

- `filters`: an object containing the new filter values
- `displayedFilters`: an object containing the new displayed filters
- `debounced`: set to false to disable the debounce (true by default)

You can use it to update the list filters:

```jsx
import { useState } from 'react';
import { useListController } from 'react-admin';

const OfficeList = () => {
const { filterValues, setFilters, data, isLoading } = useListController({ resource: 'offices' });
const [formValues, setFormValues] = useState(filterValues);

const handleChange = (event) => {
setFormValues(formValues => ({
...formValues,
[event.target.name]: event.target.value
}));
};

const handleSubmit = (event) => {
event.preventDefault();
// The 3rd parameter disables the debounce ⤵
setFilters(filterFormValues, undefined, false);
};

if (isLoading) return <div>Loading...</div>;

return (
<>
<form onSubmit={handleSubmit}>
<input name="country" value={formValues.country} onChange={handleChange} />
<input name="city" value={formValues.city} onChange={handleChange} />
<input name="zipcode" value={formValues.zipcode} onChange={handleChange} />
<input type="submit">Filter</input>
</form>
<ul>
{data.map(record => (
<li key={record.id}>{record.name}</li>
))}
</ul>
</>
);
};
```

Beware that `setFilters` is debounced by default, to avoid making too many requests to the server when using search-as-you-type inputs. In the example above, this is not necessary. That's why you should set the third argument to `setFilters` is set to `false` to disable the debounce.

Disabling the debounce with the third parameter is also necessary when you use `setFilters` and other list controller methods (like `setSort`) in a single function. Otherwise, the `setFilters` call would override the other changes.

```jsx
const changeListParams = () => {
setSort({ field: 'name', order: 'ASC' });
// The 3rd parameter disables the debounce ⤵
setFilters({ is_published: true }, undefined, false);
};
```

0 comments on commit 4b825a0

Please sign in to comment.