Как использовать состояние пользовательского редуктора в качестве постоянного фильтра в «Списке»?

У меня есть собственный редуктор и подключенный компонент для изменения его состояния. Теперь я хотел бы использовать это состояние в качестве постоянного фильтра для элементов списка. Я понимаю, что элементы списка связаны с состоянием редукции, поэтому я надеюсь, что смогу получить к нему доступ через реквизиты компонента списка, но не смог найти способ, как это сделать.


person punkjay    schedule 17.07.2018    source источник


Ответы (2)


Компонент List подключен, но не ваш.

import { connect } from "react-redux";

const MyList = ({ is_published, ...props }) => (
    <List {...props} filter={{ is_published }}>

    </List>
);

const mapStateToProps = state => ({
    is_published: state.myCustomReducer.is_published,
});

export default connect(mapStateToProps, undefined)(MyList);

Изменить:

Только что узнал, что мы не обновляем данные при изменении этого реквизита. Это ошибка, и вы можете открыть вопрос об этом.

А пока есть обходной путь: создайте настраиваемую сагу, слушающую все, что угодно. действие, которое вы используете вместе с вашим настраиваемым редуктором (в моем примере я назову его SET_IS_PUBLISHED). Эта пользовательская сага должна put создавать changeListParams действий из react-admin с вашим фильтром.

Вероятно, это будет выглядеть так (не проверено):

import { takeEvery, put, select } from 'redux-saga/effects'
import { changeListParams } from 'react-admin'
import { SET_IS_PUBLISHED } from './isPublished'

const getCurrentListParams = (state, resource) => {
    const resourceState = state.admin.resources[resource]
    return resourceState.list.params
}

function handleSetPublished({ payload }) {
    const currentParams = yield select(getCurrentListParams)
    const newParams = {
        // Keep the current params
        ...currentParams,
        // Override the filter
        filter: {
            // Keep the current filter
            ...currentParams.filter,
            // Only override the is_published
            is_published: payload
        }
    }
    // Dispatch the action for the `posts` resource
    yield put(changeListParams('posts', newParams))
}

export default function* () {
    yield takeEvery(SET_IS_PUBLISHED, handleSetPublished)
}
person Gildas Garcia    schedule 19.07.2018
comment
Не работает. Состояние редукции по какой-то причине не достигает фильтра. Фильтр работает нормально, если я ввожу туда число (состояние - это номер идентификатора). Подключение к пользовательскому состоянию редуктора отлично работает в пользовательском компоненте, который я сделал, чтобы попробовать его, поскольку я новичок в редуксе. - person punkjay; 20.07.2018
comment
Хорошо, это должно включать весь соответствующий код: codesandbox.io/s/kxmxyvoxw3. - person punkjay; 27.07.2018
comment
Есть несколько комментариев, разъясняющих некоторые моменты в коде. Также включен файл BuildingFilter, который я использовал для проверки работы редуктора. Оно делает. Я также попытался создать функцию для экспорта из этого файла и использования в BusAdapterList. Что мы хотим от этого, так это то, что у нас есть множество различных ресурсов, связанных со зданием, и мы хотели бы иметь возможность выбирать здание на панели инструментов, чтобы вам не нужно было иметь отдельный фильтр на каждой странице списка. - person punkjay; 27.07.2018
comment
Отредактировал мой ответ - person Gildas Garcia; 27.07.2018
comment
Я открою вопрос об этом - спасибо за вашу помощь. Я занимался другими делами и возвращался к этой проблеме. Еще один вопрос: вы сказали, что мы не обновляем данные при изменении этого реквизита. Означает ли это, что фильтр должен работать с начальным значением? Я попытался установить начальное состояние моего редуктора, вызвав его с помощью ComponentWillMount в компоненте, который я использую для управления состоянием. Компонент находится на моей панели инструментов. Состояние установлено, но не используется в фильтре. В любом случае, я попробую ваш обходной путь, надеюсь, он решит мою проблему :) - person punkjay; 08.08.2018
comment
Это все еще не работает после исправления. Список перерисовывается при изменении состояния, но значения фильтра, которые передаются в вызове API, остаются старыми. Кто-нибудь еще пробовал это? - person manuelamaria; 14.04.2019
comment
Я установил codeandbox для этого здесь. У меня есть два элемента в списке, и постоянный фильтр - это идентификатор. Значение по умолчанию — 0. При нажатии флажка «Изменить идентификатор на 1» вверху состояние изменяется на 1, поэтому в списке должен отображаться пост с идентификатором 1. Значение nextProps верное. Однако я получаю сообщение об ошибке в консоли, не знаю почему. В моем реальном приложении ошибки нет, но список по-прежнему фильтруется по старому значению состояния. При каждом последующем щелчке флажка список фильтруется с предыдущим значением. Любая помощь будет оценена по достоинству. - person manuelamaria; 14.04.2019

просто чтобы перенести это в 2021 год, вы можете использовать хук useSelector redux, чтобы получить ваше пользовательское состояние:

import { useSelector } from 'react-redux';
const MyCustomThing = (props) => {
  const is_published = useSelector(state => state.customState.is_published);
}

Для полноты, react-admin предоставляет свойство customReducers для своего компонента <Admin>, чтобы вы могли расширить состояние редукции своими пользовательскими значениями:

const customStateReducer = (customState = { is_published: false }, { type, payload }) => {
  if (type === 'IS_PUBLISHED') customState.is_published = payload.is_published;
  return customState;
}

<Admin customReducers={{ customState: customStateReducer }} ...>
etc
person Andy Lorenz    schedule 17.03.2021