Redux 如何更新计算状态

Redux how to update computed state

我正在学习 redux(在 Flutter 中使用 Firestore,但我认为这并不重要),试图超越基础知识,但我对 'computed state' 在哪里感到困惑(甚至不确定是什么调用它)应该去。

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

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

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

这些选择是否全部有效?我希望这是一个有意义的问题。我什至可能太落后了,无法正确地提出这个问题。

你已经接近计算状态了。来自 documentation

Reselect provides a function createSelector for creating memoized selectors. createSelector takes an array of input-selectors and a transform function as its arguments. If the Redux state tree is changed in a way that causes the value of an input-selector to change, the selector will call its transform function with the values of the input-selectors as arguments and return the result. If the values of the input-selectors are the same as the previous call to the selector, it will return the previously computed value instead of calling the transform function.

这基本上就是你懒惰选择电影的目的。

在状态下,您存储用户和电影。一些电影被标记为特定用户的最爱(因此当用户将电影标记为最爱时,您只修改电影而不是 re-run 选择器)。

当某些组件需要最喜欢的电影列表时,它会调用选择器来计算派生状态(最喜欢的电影列表)并 returns 它。此外,选择器将记住结果并仅在存储更改时重新计算它们,而不是在每次渲染时重新计算。

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

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

计算状态在 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 and/or 中间件可以计算最喜欢的电影列表。但这不是他们的责任。因此,为了更好地分离关注点,最好使用选择器来完成此任务。

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