Redux如何更新计算状态

时间:2019-06-20 15:32:13

标签: redux flutter-redux

我正在学习redux(在使用Firestore的Flutter中使用,但我认为不重要),试图超越基础知识,并且我对“计算状态”的位置感到困惑(甚至不确定该怎么称呼它) )应该走。

说我的应用状态如下:

  • 用户:用户的实例
  • 电影:用户的电影列表
  • recentFavoriteMovie :该用户上方的其中一部电影已标记为“收藏夹”,并且具有最近的创建日期

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

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

所有这些选择还是全部有效?我希望这是一个合理的问题。我什至可能跟不上弯路,无法正确地提出这个问题。

1 个答案:

答案 0 :(得分:1)

您几乎拥有计算状态。来自documentation

  

重新选择提供了用于创建备注选择器的功能createSelectorcreateSelector将输入选择器数组和一个转换函数作为其参数。如果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和/或中间件可以计算喜欢的电影列表。但这不是他们的责任。因此,为了更好地分离关注点,最好使用选择器来完成此任务。

也没有理由使用特定的中间件(成功的中间件)。您可以在动作和化简器中实现逻辑。