Redux как обновить вычисляемое состояние - PullRequest
1 голос
/ 20 июня 2019

Я изучаю редукс (во Flutter, используя Firestore, но я не думаю, что это имеет значение), пытаюсь выйти за рамки основ, и я запутался в том, где «вычисленное состояние» (даже не уверен, как его назвать.) должен идти.

Скажем, у меня есть состояние приложения, подобное этому:

  • пользователь : экземпляр пользователя
  • фильмы : список фильмов пользователя
  • RecentFavoriteMovie : один из фильмов выше этого пользователя помечен как «избранный» и имеет самую последнюю дату создания

Я могу установить пользователя (действие при успешном входе в систему) и запросить фильмы пользователя (промежуточное ПО для успешного входа в систему).Когда запрос к фильму завершается, я не понимаю, где инициализировать recentFavoriteMovie.Кажется, есть много вариантов ....

  1. Промежуточное ПО SetMovies может вычислить его, а затем вызвать действие SetRecentFavorite.
  2. Может ли редуктор SetMovies сделать это?Или это считается побочным эффектом редуктора, который недопустим?
  3. Я бы хотел сделать это лениво.Считается ли в редуксе нормальным предоставление объекту состояния приложения метода, который вычисляет и кэширует его?Если это так, мне все равно нужно очистить кэшированное значение при установке нового списка фильмов.Но это похоже на ту же проблему, что и (b) выше.
  4. Я мог бы поместить свойство movies и FavoritesMovies (свойство или метод) в мой пользовательский объект (они там вроде как), а затем просто отправить действие UpdateUser.каждый раз, когда один или другой меняется.В общем, я не знаю, когда / нужно ли «продвигать» какой-либо податрибут состояния моего приложения на верхний уровень, чтобы приложение могло на него реагировать.

Все или некоторые из них действительнывыбор?Я надеюсь, что это имеет смысл как вопрос.Возможно, я даже слишком за кривой, чтобы спросить это правильно.

1 Ответ

1 голос
/ 21 июня 2019

Вы почти что с вычисленным состоянием.Из документации

Реселект предоставляет функцию createSelector для создания запомненных селекторов.createSelector принимает массив входных селекторов и функцию преобразования в качестве аргументов.Если дерево состояний Redux изменяется таким образом, что вызывает изменение значения селектора ввода, селектор вызовет свою функцию преобразования со значениями селекторов ввода в качестве аргументов и вернет результат.Если значения селекторов ввода совпадают с предыдущими вызовами селектора, он будет возвращать ранее вычисленное значение вместо вызова функции преобразования.

Это, по сути, то, что вы хотите с ленивымвыбор фильмов.

В состоянии вы храните пользователя и фильмы.Некоторые фильмы помечены как избранные для определенного пользователя (поэтому, когда пользователь помечает фильм как избранный, вы изменяете только фильмы, а не перезапускаете селектор).

Когда некоторому компоненту требуется список избранных фильмов, он вызывает селектор, который вычисляет производное состояние(список любимых фильмов) и возвращает его.Кроме того, селектор запомнит результаты и пересчитает их только при сохранении изменений, но не при каждом рендеринге.

Этот подход можно считать оптимальной практикой, так как позже вы сможете реализовать некоторые фильтры для списка фильмов, а селекторы помогут извлечь отфильтрованный списокфильмы.

При использовании селектора вам не требуется хранить выбранные данные (список избранных фильмов) в своем магазине.

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

const makeMapStateToProps = () => {
    const getFavoriteMovies = makeGetFavoriteMovies();
    const mapStateToProps = (state) => (
    {
        favoriteMovies: getFavoriteMovies(state.user, state.movies),
        movies: state.movies,
        user: state.user
    });
    return mapStateToProps;
}

и makeGetFavoriteMovies могут выглядеть так:

const getFavoriteMovies = (state) => state.movies;
const getUser = (state) => state.user;

export function makeGetFavoriteMovies () {
    return createSelector(
        [getFavoriteMovies, getUser],
        (favoriteMovies, user) => {
            // Here can be complicated logic to select only favorite movies
            return movies.filter (movie => movie.isFavorite); 
        }
    );
)

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

Также нет причин для конкретного промежуточного программного обеспечения (промежуточное программное обеспечение ogin success).Вы можете реализовать логику в действиях и редуктор.

...