Reactjs React路由器/Redux应用中的数据/模型管理
我想知道在使用Reactjs React路由器/Redux应用中的数据/模型管理,reactjs,data-structures,redux,data-management,Reactjs,Data Structures,Redux,Data Management,我想知道在使用React-Router和Redux的React应用程序中加载服务器数据的最佳方法是什么。 例如:访问/dossier/123时,我只想检索该特定档案的数据。导航到/档案时,我希望显示有关所有项目的“部分”数据(标题、说明、所有者等)。 这意味着,我的模型看起来像这样: { dossiers: IDossier[]; } interface IDossier { id: number; title: string; description: str
React-Router
和Redux
的React应用程序中加载服务器数据的最佳方法是什么。
例如:访问/dossier/123
时,我只想检索该特定档案的数据。导航到/档案时,我希望显示有关所有项目的“部分”数据(标题、说明、所有者等)。
这意味着,我的模型看起来像这样:
{
dossiers: IDossier[];
}
interface IDossier {
id: number;
title: string;
description: string;
owner: IUser;
codes?: ICode[];
template?: ITemplate;
}
在/dossier/123处“输入”应用程序时,“初始”状态如下
{
dossiers: [{
id: 123,
title: "My dossier",
description: "...",
owner: { id: 1; name: "John Doe" },
codes: [{ ... }, { ... }],
template: { ... }
}]
}
但是,在输入at/档案时,初始状态看起来更像
{
dossiers: [{
id: 123,
title: "My dossier",
description: "...",
owner: { id: 1; name: "John Doe" }
}, {
id: 456,
title: "Another dossier",
description: "...",
owner: { id: 2; name: "Jane Doe" }
}, {
...
}]
}
当导航到/dossier/123或/dossier/456时,我需要某种指示,我必须加载代码和模板信息,因为它们尚未获取-至少不是我第一次进入url端点
所以我想我的主要问题是:当数据在应用程序中来回导航时,我如何以稳健的方式管理它,而不需要在存储中已经可用的情况下重新获取数据。每次需要加载某个档案实例或整个集合时,您应该首先查看存储中已有的数据,并确定是否需要调用API。由你来决定。有些应用程序可能会在每次打开页面时刷新数据,有些应用程序每天最多刷新一次 如果有多个不同的数据集合具有相同的逻辑-例如,数组中的对象具有
id
,这些对象在第一次加载时从未刷新过-那么您可能应该对该逻辑进行抽象,这样您就不需要重复自己
我建议使用函数式编程。更具体地说,是高阶函数
例如,创建一个通用的集合加载器
// Collection loader “constructor”.
const createCollectionLoader = (store, selector, actionPrefix) => {
// Actual collection loader.
return {
// Function that makes sure collection is loaded.
loadAll: () => {
const collection = selector(store.getState());
const shouldLoad = …; // Decide if it should load.
if (shouldLoad) {
store.dispatch({ type: `${actionPrefix}_LOAD`, data });
try {
const data = …; // Load.
store.dispatch({ type: `${actionPrefix}_LOAD_SUCCESS`, data });
} catch (error) {
store.dispatch({ type: `${actionPrefix}_LOAD_ERROR`, error });
}
}
},
// Function that makes sure single collection item is loaded.
load: (id) => {
const collection = selector(store.getState());
const item = collection.find(item => item.id === id);
const shouldLoad = …; // Decide if it should load.
if (shouldLoad) {
store.dispatch({ type: `${actionPrefix}_ITEM_LOAD`, data });
try {
const data = …; // Load.
store.dispatch({ type: `${actionPrefix}_ITEM_LOAD_SUCCESS`, data });
} catch (error) {
store.dispatch({ type: `${actionPrefix}_ITEM_LOAD_ERROR`, error });
}
}
},
};
};
然后为您拥有的每个集合创建loader
const dossiersLoader = createCollectionLoader(store, state => state.dossiers, 'DOSSIERS');
最后,每次您想要确保档案(或单个档案已加载)时,调用适当的加载程序函数
dossiersLoader.loadAll();
// or
dossiersLoader.load(id)
为了使它更好,引入一个表示工作单元的抽象——称之为任务、作业、过程、传奇等等
我更喜欢将React web应用程序代码分为三个不同的组:UI、状态和逻辑。为此,我建议分别使用
react
(显然),react-redux
,以及redux-saga
。看到许多高阶组件、传奇甚至减速机并不罕见。感谢@jokka的解释。虽然我希望有一些更通用的模式,而不是//决定是否加载部分:),但很难概括关于数据刷新的实际决定,因为在整个应用程序中它变化很大-取决于,例如,你是否有显式刷新按钮,数据是否变化迅速等等,听起来你已经对逻辑下了决心。问题是什么?你应该跳过加载还是怎么做?