question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Custom function passed into setFilters doesn't get called

See original GitHub issue

What you were expecting: setFilters callback to get called when user types into SearchInput component.

What happened instead: The custom setFilters function parsed into Filter component doesn’t get called. Instead, the default setFilters get called with the value in the searchInput instead.

Steps to reproduce:

  1. in PostFilter component (from codesandbox), pass in a custom function to the setFilter prop with a console log. Please see below in related code area or in codesandbox for reference.
  2. Type in the search box, expect console log to show
  3. console log doesn’t show. Instead the setFilter was default to the function below function (filters, displayedFilters) { return debouncedSetFilters(filters, displayedFilters); } which is not the input function into props of Filter component. Perhaps the above function came from here? useListParams

Related code:

CodeSandbox with sample issue link https://codesandbox.io/s/restless-https-x3d05?file=/src/posts/PostList.js:1185-1226 forked from https://codesandbox.io/s/github/marmelab/react-admin/tree/master/examples/simple

As shown in the CodeSandbox above I would expect the below code to show a console.log(“inside customSetFilters”) on the console, but the function customSetFilters never get called so the log never appears.

const PostFilter = (props) => {
  const { setFilters, ...rest } = props;

  const customSetFilters = (filter) => {
    console.log("inside customSetFilters");
    return setFilters(filter);
  };

  return (
    <Filter setFilters={customSetFilters} {...rest}>
      <SearchInput source="q" alwaysOn />
      <TextInput
        source="title"
        defaultValue="Qui tempore rerum et voluptates"
      />
      <QuickFilter
        label="resources.posts.fields.commentable"
        source="commentable"
        defaultValue
      />
    </Filter>
  );
};

Other information:

My suspicion here is that for some reason filterForm doesn’t call the correct setFilters function here https://github.com/marmelab/react-admin/blob/dcb2a2e71f595dff8440d64001d033aa2d98afa1/packages/ra-ui-materialui/src/list/filter/FilterForm.tsx#L193

Environment

  • React-admin version:3.8.4
  • React version: 16.13.1
  • Browser: Chrome
  • Stack trace (in case of a JS error):

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:2
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
fzaninottocommented, Sep 24, 2020

Now I understand the problem.

useListContext normally returns the setFilters callback from the context. However, to avoid breaking compatibility when introducing the ListContext, we’ve passed the props to useListContext. That way, If you use Filter outside of a ListContext, it will grab the setFilters callback from the props.

But in your case, you are inside a ListContext (it’s created by List). The fallback to props doesn’t work in this case.

The fix on your side is to pass your custom setFilters not via props, by via a custom ListContext. Something like:

import { useListContext, ListContextProvider } from 'react-admin'.
const Filters = ({ setFilters, filterValues, ...rest }) => {
  const { customSetFilters, customFilterValues } = useSearchWithCustomFilters({
    filterToQuery,
    queryToFilter,
    filterValues,
    setFilters,
    searchKey: searchQueryKey,
  });
  const listContext = useListContext();

  return (
    <ListContextProvider value={{ ...listContext, setFilters: customSetFilters, filterValues: customFilterValues }}> 
      <Filter {...rest}>
        <StyledSearchInput
          placeholder="Search for bookings..."
          source="query"
          alwaysOn
        />
      </Filter>
    </ListContextProvider>
  );
};

As a side note, overriding the setFilters callback wasn’t a documented feature, and as such isn’t supported. So I don’t think this is really a bug in react-admin and I’m not sure we should fix it.

0reactions
charlie-tttcommented, Sep 30, 2020

@fzaninotto Thank you Francois. Your explanation made sense. Tried it on my end with the method you suggested and things work well now. 🙆‍♂️

Read more comments on GitHub >

github_iconTop Results From Across the Web

react-table setFilter with custom filter function? - Stack Overflow
I am trying to set a filter on a column using react-table . I'd like a checkbox change to filter multiple possible values...
Read more >
React-admin - Filtering the List
React-admin proposes several UI components to let users see and modify filters, and gives you the tools to build custom ones. The Filter...
Read more >
Filtering Data - Tabulator
To set a filter you need to call the setFilter method, passing the field you ... The != filter displays only rows whith...
Read more >
Vue Grid: Filter Component
(): void; // Gets called when the column is destroyed. If your custom filter needs to do // any resource cleaning up, do...
Read more >
React interactivity: Editing, filtering, conditional rendering
We don't have a user interface for editing the name of a task yet. ... Add the editTask() function inside your App component,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found