我遇到了一个有趣的问题。
用例是这样的:
渲染个人资料时(无论是地点还是用户个人资料),我想从服务器中检索一些信息。
减速器看起来像这样:
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返回一个位置)。
我在这里有效执行的操作是更新“地方对象”,这是一个副作用,我只返回一个地方(我需要的组件中的位置)。
尽管我认为这会起作用,但我不认为这是最好的方法。
您如何改善现有设计?
答案 0 :(得分:0)
给定的示例无法按预期工作,因为switch语句中的返回值将始终更新当前状态。
因此,以与初始状态不同的格式返回值不是一个好习惯,因为它导致不一致的状态。
对于我的用例,解决方案非常简单。
由于当前显示的配置文件包含需要实时信息的信息(即该配置文件有多少观察者),因此我需要在每个页面浏览中再次请求数据。
我将状态与一个配置文件与另一个配置文件隔离的方式是,在FETCH_PLACE_REQUEST
上返回一个空对象。这样可以确保在请求新配置文件时始终清空该状态。