Redux如何更新计算状态

Redux如何更新计算状态,redux,flutter-redux,Redux,Flutter Redux,我正在学习redux(在使用Firestore的Flatter中,但我认为这并不重要),试图超越基本知识,我对“计算状态”(甚至不知道该怎么称呼它)应该去哪里感到困惑 假设我的应用程序状态如下: 用户:用户的实例 电影:用户电影列表 recentFavoriteMovie:该用户上面的一部电影已标记为“收藏夹”,并具有最新的创建日期 我能够设置用户(登录成功操作)和请求用户的电影(登录成功中间件)。当电影查询完成时,我不知道在哪里初始化recentFavoriteMovie。似乎有很多选择

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

假设我的应用程序状态如下:

  • 用户:用户的实例
  • 电影:用户电影列表
  • recentFavoriteMovie:该用户上面的一部电影已标记为“收藏夹”,并具有最新的创建日期
我能够设置用户(登录成功操作)和请求用户的电影(登录成功中间件)。当电影查询完成时,我不知道在哪里初始化
recentFavoriteMovie
。似乎有很多选择

  • SetMovies中间件可以计算它,然后调用SetRecentFavorite操作
  • 这台机器能做到吗?或者这被认为是减速器的副作用,这是不允许的
  • 我喜欢懒洋洋地做这件事。在redux中,给应用程序状态对象一个计算和缓存它的方法可以吗?如果是这样,我仍然需要在设置新电影列表时清除缓存的值。但这似乎和上面(b)的问题一样
  • 我可以将movies属性和favoriteMovies(属性或方法)放在我的用户对象中(它们有点属于那里),然后在每次一个或另一个更改时发送UpdateUser操作。一般来说,我不知道何时/是否将我的应用程序状态的某些子属性“升级”到顶层,以便应用程序可以对此作出反应

  • 这些选择全部或任何一个都是有效的吗?我希望这是一个有意义的问题。我甚至可能太落伍了,不能正确地问这个问题。

    你几乎用计算状态回答了。从

    重新选择提供了一个函数
    createSelector
    ,用于创建记忆选择器
    createSelector
    将输入选择器数组和转换函数作为其参数。如果Redux状态树的更改导致输入选择器的值更改,则选择器将使用输入选择器的值作为参数调用其转换函数并返回结果。如果输入选择器的值与先前调用选择器的值相同,则它将返回先前计算的值,而不是调用transform函数

    这正是俞敏洪想要的懒散的电影选择

    在该状态下,您存储用户和电影。某些电影标记为特定用户的收藏夹(因此,当用户将电影标记为收藏夹时,您仅修改电影,而不重新运行选择器)

    当某些组件需要收藏电影列表时,它调用选择器,该选择器计算派生状态(收藏电影列表)并返回它。此外,选择器将记住结果,并仅在存储更改时重新计算结果,而不是在每个渲染上

    这种方法可以被认为是最佳实践,因为您以后可能会为电影列表实现一些过滤器,选择器将有助于提取过滤后的电影列表

    使用选择器时,您不需要在存储中存储选定的数据(最喜爱的电影列表)

    计算状态在
    MapStateToros
    中用于需要计算状态的每个组件,如

    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成功中间件)。您可以在actions和reducer中实现逻辑