Как не изменить URL-адрес при фильтрации списка с помощьюact-admin? - PullRequest
1 голос
/ 23 января 2020

Предположим, у меня есть маршрут / клиенты, для которых Список из клиентов отображается. На этом же маршруте также присутствует боковой ящик . Этот ящик содержит список с фильтром из разделов справки .

Когда я начинаю вводить фильтр в боковом ящике, URL-адрес изменяется. Это в соответствии с тем, как работает фильтр списка реакции-администратора.

Проблема в том, что список клиентов замечает изменения маршрута. Фактически он начинает запрашивать и перезагружать клиентов на основе поискового запроса, связанного с разделами справки . Клиентов, конечно, не найдено.

Я хочу, чтобы список клиентов не замечал, что я фильтрую по темам справки. Решение, к которому я стремлюсь, заключается в том, что фильтр списка в боковом ящике не изменит URL, пока я ввожу поисковый запрос topi c.

Как настроить или настроить фильтр на стороне ящик, чтобы не изменять URL при вводе, а вместо этого хранить текущее значение фильтра в чем-то вроде состояния компонента?

На самом деле, поскольку фильтр живет в форме (по реакции-финальной-форме), которая сохраняет свою собственную состояние, я мог бы жить с таким решением. Но, конечно, publishToUrl не является доступной опорой для Filter.

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

Связанный:

Ответы [ 3 ]

1 голос
/ 30 января 2020

Свойство setFilters () передается компоненту Filter из его родительского списка.

Так что вам нужно реализовать свой собственный хук useListParams с удаленными / обернутыми строкой с комментариями условий:

const changeParams = useCallback(action => {
        const newQuery = getQuery({
            location,
            params,
            filterDefaultValues,
            sort,
            perPage,
        });
        const newParams = queryReducer(newQuery, action);
        // history.push({
        //     search: `?${stringify({
        //         ...newParams,
        //         filter: JSON.stringify(newParams.filter),
        //     })}`,
        // });
        dispatch(changeListParams(resource, newParams));
    }, requestSignature); // eslint-disable-line react-hooks/exhaustive-deps

Затем вам нужно реализовать useListController и вызывать свой хук вместо реакции-admin.

const [query, queryModifiers] = useListParams({
    resource,
    location,
    filterDefaultValues,
    sort,
    perPage,
    debounce,
});

Наконец вы реализуете компонент List и передаете свой новый классный useListController. Значения фильтра не будут отражены в строке запроса, а также в разбивке по страницам и сортировке.

Другой и более простой способ - перехватить вызов setFilters в вашем компоненте Filter и выполнить

dispatch(changeListParams(resource, newParams));

с новыми значениями фильтра без связки реализации и компонентов.

0 голосов
/ 28 марта 2020

Я пробовал другое решение, возможно, оно кому-нибудь поможет:

const FunctionsFilter = ({resource, ...rest}) => {
    const classes = useStyles();
    const location = useLocation();
    const [query, queryModifiers] = useMyListParams({
        resource,
        location,
        filterDefaultValues: {},
        sort: {
            field: 'name',
            order: 'asc',
        },
        perPage: 5,
        debounce: 500,
    });
    return (
        <Filter resource={resource} {...rest} setFilters={queryModifiers.setFilters}>
            <TextInput className={classes.dialogformfilter} source="name" alwaysOn resettable/>
        </Filter>
    );
};

Теперь по какой-то причине он отправляет запрос дважды, поэтому я также скопировал useListController в useMyListController, а теперь он отправляет его только один раз. Недостатком является то, что вы должны поддерживать его при обновлении версии.

Кроме того, комбинация решения Christiaan Westerbeek с useMyListController, работала лучше всего для меня.

0 голосов
/ 30 января 2020

Благодаря указаниям, предоставленным d0berm4n, я смог скомпилировать рабочее решение (дляact-admin 3.x). Он довольно ограничен с точки зрения создаваемого запроса (просто фильтр), но он просто необходим мне.

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;

Обновление: это решение неполное. Другие фильтры на той же странице теперь начинают запрашивать список, в который включен MyFilter. Я подозреваю, что это проблема, которую я могу изолировать. Подробнее об этом позже ...

...