Search code examples
urlfilterreact-admin

How to not change the url on list filtering with react-admin?


Assume I have a route /customers where a List of customers is being rendered. On that same route there's also a side drawer present. That drawer contains a List with a Filter of help topics.

When I start typing in the Filter in the side drawer, the url changes. That's according to how react-admin's list filter is working.

The problem is that the customers list is noticing the route changes. In effect it starts querying and reloading customers based on a search term that is related to help topics. No customers found of course.

I want the customer list to not notice I'm filtering on help topics. The solution I'm aiming for is that the list filter in the side drawer will not change the url while I input a help topic search term.

How can I configure or customise the filter in the side drawer to not change the url while typing, but store the current filter value in something like component state instead?

Actually, since the filter lives in a form (by react-final-form), which keeps its own state, I could live with a solution like this. But of course publishToUrl isn't an available prop for Filter.

const MyFilter = props => (
    <Filter {...props} publishToUrl={false} >
        <TextInput source="title" />
    </Filter>
);

Related:


Solution

  • Thanks to the directions provided by d0berm4n, I was able to compile a working solution (for react-admin 3.x). It's pretty limited in terms of the query that it creates (just filter), but it's just wat I need.

    import React, { useCallback } from 'react';
    import PropTypes from 'prop-types';
    import { useDispatch } from 'react-redux';
    import lodashDebounce from 'lodash/debounce';
    import { Filter, TextInput, changeListParams } from 'react-admin';
    
    const MyFilter = ({ resource, ...rest }) => {
        const dispatch = useDispatch();
    
        const debouncedSetFilters = lodashDebounce((filter = {}) => {
            const query = { filter };
    
            dispatch(changeListParams(resource, query));
        }, 500);
    
        const setFilters = useCallback(debouncedSetFilters, []);
    
        return (
            <Filter resource={resource} {...rest} setFilters={setFilters}>
                <TextInput source="title" alwaysOn resettable />
            </Filter>
        );
    };
    MyFilter.propTypes = {
        resource: PropTypes.string,
    };
    MyFilter.displayName = 'MyFilter';
    
    export default MyFilter;
    

    Update: This solution is incomplete. Other filters on the same page are now starting to query on the List that MyFilter is on. I suspect that's a problem that I can isolate. More on this later...