1

我正在学习 redux(在 Flutter 中使用 Firestore,但我认为这并不重要),试图超越基础知识,我对“计算状态”(甚至不知道该怎么称呼它)应该去哪里感到困惑.

假设我有这样的应用程序状态:

  • 用户:用户的一个实例
  • 电影:用户电影列表
  • 最近最喜欢的电影:用户标记为“最喜欢”并具有最近创建日期的上述电影之一

我能够设置用户(登录成功操作)并请求用户的电影(登录成功中间件)。电影查询完成后,我对在哪里进行初始化感到困惑recentFavoriteMovie。似乎有很多选择......

  1. SetMovies 中间件可以计算它,然后调用 SetRecentFavorite 动作。
  2. SetMovies 减速器能做到吗?或者这是否被认为是减速器的副作用,这是不允许的?
  3. 我想偷懒。在 redux 中是否可以为应用程序状态对象提供一个计算和缓存它的方法?如果是这样,我仍然需要在设置新电影列表时清除缓存值。但这似乎与上面的(b)相同。
  4. 我可以将 movies 属性和 favoriteMovies (属性或方法)放在我的用户对象中(它们有点属于那里),然后每次一个或另一个更改时只调度一个 UpdateUser 操作。一般来说,我不知道何时/是否将我的应用程序状态的某些子属性“提升”到顶层,以便应用程序对其做出反应。

这些是所有或任何一个有效的选择吗?我希望这是一个有意义的问题。我什至可能太落后了,无法正确地问这个问题。

4

1 回答 1

1

你几乎有计算状态。从文档

Reselect 提供了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); 
        }
    );
)

Reducer 和/或中间件可以计算最喜欢的电影列表。但这不是他们的责任。因此,为了更好地分离关注点,最好使用选择器来完成这项任务。

也没有特定中间件的理由(ogin 成功中间件)。你可以在 action 和 reducer 中实现逻辑。

于 2019-06-21T06:35:23.107 回答