【发布时间】:2020-11-07 18:56:01
【问题描述】:
我想允许用户多次将同一个服务器项添加到页面(id:5)。为了在我们的应用程序中跟踪这些项目,我们需要为每个实例生成一个唯一的 ID。
我们的项目具有关系数据,因此出于性能原因,我们可能会在 redux 存储中标准化 API 响应。
type Item = { id: string; }
type Sku = { id: string; }
type AppStore = {
items: { [id: string]: Items },
skus: { [id: string]: Skus },
itemSkus: { [id: string]: string[] },
}
使用此 API
export interface IAPIResponse<T> {
data?: T;
errors?: string[];
}
type IAPIItem = {
id: string;
skus: Array<{
id: string;
}>;
}
在典型的 redux-thunk action creator 中请求数据:
export const addItem = () => async (dispatch) => {
dispatch(startedAddItem());
try {
const response = await get <IAPIResponse<IAPIItem>>('/get/item/5');
dispatch(succeededAddItem(response));
} catch (error) {
console.error('Error', error);
dispatch(failedAddItem(error));
}
};
并用他们的相关数据填充我们的减速器:
// items reducer
case ItemAction.addSucceeded:
const apiItem = getApiResource(action.payload);
const apiErrors = getApiErrors(action.payload);
if (apiErrors) // Handle errors in state
if (apiItem) {
const item = buildItem(apiItem);
return {
...state,
[item.id]: item,
}
}
break;
// skus reducer
case ItemAction.addSucceeded:
const apiItem = getApiResource(action.payload);
const apiErrors = getApiErrors(action.payload);
if (apiErrors) // Handle errors in state
if (apiItem) {
const skus = buildSkus(apiItem.skus);
const indexedSkus = { ...skus.map(s => ({ [s.id]: s })) };
return {
...state,
...indexedSkus,
}
}
break;
// itemSkus reducer
case ItemAction.addSucceeded:
const apiItem = getApiResource(action.payload);
const apiErrors = getApiErrors(action.payload);
if (apiErrors) // Handle errors in state
if (apiItem) {
const item = buildLineItem(apiItem);
const skus = buildSkus(apiItem.skus);
return {
[item.id]: skus.map(s => s.id),
}
}
break;
在这种模式下,我们无法可靠地为 Item 和 Skus 生成相同的唯一 ID,因为响应在多个 reducer 中进行解析。 Redux 建议我们必须在它到达 reducer 之前生成唯一 ID。
问题:我怎样才能适应这种模式来解析reducer之前的响应,同时保持读取嵌套api数据和解析reducer中的响应体错误的灵活性?
【问题讨论】:
-
我对“具有多个实例的商店项目”评论感到困惑。您能否为您正在尝试做的事情以及为什么/如何做进一步的解释?
-
@markerikson 抱歉,我已经更新了那部分 :) 假设您正在制造一辆汽车并想要添加四个轮胎。轮胎在服务器上具有相同的 ID。但是在我们的客户端应用程序中,我们需要为每个轮胎生成一个唯一的 id 来跟踪它。
-
那么从应用程序用户流中,您需要在这个序列中的哪个位置开始使用这些 ID? “多个实例”实际上是从服务器返回的,还是根据用户交互在客户端上随着时间的推移添加的(即“添加左前轮胎”)?
-
@markerikson 他们从服务器回来,即。用户单击“添加轮胎”,然后出现一个对话框,他们从数据库中选择预先存在的轮胎。所以他们添加了四个相同的轮胎。在将轮胎添加到 redux 商店之前,我需要生成 ID
-
那么服务器是否真的返回了
tires: [{}, {}, {}, {}]?如果是这样,为什么不让服务器生成这些唯一 ID?还是我误解了这里的用法? (另请注意,目前这可能更容易在 Reactiflux#redux频道中讨论)。
标签: reactjs typescript redux api-design redux-thunk