redux减速器的副作用,减速器返回值的形式不同于初始状态

时间:2019-07-12 13:15:49

标签: javascript reactjs redux

我遇到了一个有趣的问题。
用例是这样的:

渲染个人资料时(无论是地点还是用户个人资料),我想从服务器中检索一些信息。
减速器看起来像这样:

import {
    FETCH_PLACE_SUCCESS,
} from './GetPlaceActions';

const initialState = {};

/**
 * This reducer keeps track of all places that have previously been retrieved
 * If the store contains a place that has already been added, it will return it
 * @param previousState
 * @param type
 * @param payload
 * @returns {*}
 * @constructor
 */
const GetPlaceReducer = (previousState = initialState, { type, payload }) => {

    let place = null;

    switch (type) {
      case FETCH_PLACE_SUCCESS:
          place = payload.place;
          previousState[place.placeId] = place;
          return { ...place };

      default:
          if (payload && payload.placeId) {
            place = { ...previousState[payload.placeId] }
          }
          return { ...place };
    }
};

这里的想法是跟踪先前已获取的配置文件。
我认为reducer不应包含有关“当前”位置的信息,因为当前状态可能指向错误(先前的配置文件),并且应该将它们隔离开来,因为很容易出错。
使用SSR时,此状态对象很可能在到达客户端时已经在存储中包含一个配置文件,因此,我无需再次重新获取它。

我用这种方法遇到的问题是这不是一个纯函数,并且返回的状态没有相同形式的初始状态(初始状态是一个集合,而reducer返回一个位置)。

我在这里有效执行的操作是更新“地方对象”,这是一个副作用,我只返回一个地方(我需要的组件中的位置)。
尽管我认为这会起作用,但我不认为这是最好的方法。

您如何改善现有设计?

1 个答案:

答案 0 :(得分:0)

给定的示例无法按预期工作,因为switch语句中的返回值将始终更新当前状态。
因此,以与初始状态不同的格式返回值不是一个好习惯,因为它导致不一致的状态。

对于我的用例,解决方案非常简单。
由于当前显示的配置文件包含需要实时信息的信息(即该配置文件有多少观察者),因此我需要在每个页面浏览中再次请求数据。

我将状态与一个配置文件与另一个配置文件隔离的方式是,在FETCH_PLACE_REQUEST上返回一个空对象。这样可以确保在请求新配置文件时始终清空该状态。