让我们假设你有一个使用Redux的书籍应用程序,其中包含一些功能:
现在让我们说所有这些不同的模块,以及所有这些模块的共同特征是能够搜索书籍(即搜索要购买的书籍,添加到心愿单的书籍,要查看的书籍)等等。)
这些搜索结果将存储在状态树的多个切片中。
状态树的示例可能如下所示:
{
bookStore: {
booksSearchResults: [],
...,
},
wishlist: {
booksSearchResults: [],
...,
},
reviews: {
newReview: {
booksSearchResults: [],
...,
},
...
},
...
}
有关于管理此类事情的最佳做法吗?是否只是拥有一个booksSearch
状态片并通过共享组件进行管理?
如果您可能需要在同一屏幕上的多个位置搜索图书(例如,除了应用程序主要部分中的搜索组件外,您可能在导航栏中有自动完成搜索功能)?< / p>
是另一种重用搜索逻辑的方法,并以某种方式让它更新状态的不同部分(如果有的话,是否存在实现此目的的东西)?
答案 0 :(得分:2)
redux应用程序中的可重用组件有一个很好的模式,对您有用。这假设搜索从redux的角度使用相同的api和逻辑,并为逻辑使用一个或多个可重用的组件。
在此示例中,我将<AutoCompleteSearch />
和<FullSearch />
用作UI组件,每个组件都可以在应用程序或同一页面中多次出现。
此处使用的模式是为每个组件分配一个唯一的道具,此处命名为searchId: string
,例如<AutoCompleteSearch searchId="wishlist" />
。
然后,组件在所有与搜索相关的操作的有效载荷中传递此id,例如,
{
type: SEARCH,
payload: {
term: "Harry Potter",
searchId: "wishlist",
}
}
搜索缩减器的结构为searchId
为关键字的地图。 redux状态的示例:
{
wishlist: {
inProgress: true,
searchTerm: "Harry Potter",
results: [],
},
reviews: {
inProgress: false,
searchTerm: "",
results: [],
},
}
然后reducer选择要处理的状态部分:
const reducer = (state, action) => {
switch(action.type) {
case SEARCH:
return {
...state,
[action.payload.searchId]: {
inProgress: true,
searchTerm: action.payload.searchTerm,
results: [],
}
};
default:
return state;
}
对于使用此模式进行数据加载的现成库,请参阅redux-autoloader。
答案 1 :(得分:2)
我有两条建议:
这是有据可查的,所以我在这里不太深入。可以说,规范化您的商店将是灵活的,并帮助您推理您的应用程序。您可以将您的商店视为服务器端数据库,并且与您根据视图定制州的每个部分相比,它将更具可重用性。
您可以通过以下方式为您的应用做到这一点:
{
books: {
bookId: {
bookDetails,
reviews: [ reviewId ],
ownedBy: [ userId ],
wishlistedBy: [ userId ],
recommendations: [ recommendationId ]
}
},
users: {
userId: {
userDetails,
reviews: [ reviewId ],
wishlist: [ bookId ],
ownedBooks: [ bookId ],
friends: [ userId ],
sentRecommendations: [ recommendationId ],
receivedRecommendations: [ recommendationId ]
}
},
reviews: {
reviewId: {
bookId,
userId,
reviewDetails
}
},
recommendations: {
recommendationId: {
sender: userId,
recipient: userId,
bookId,
recommendationDetails
}
}
}
你可能不需要所有这些关系,所以不要觉得你必须实现所有这些。但是从类似于此的基础开始将使以后更容易添加功能。
资源:
搜索结果更多地是视图详细信息,而不是数据问题。您可能需要存储搜索的历史记录,在这种情况下,您可以为搜索添加减速器:
{
searches: [
{
searchTerm,
searchDetails
}
]
}
但即使在这种情况下,我也不认为我会存储搜索结果。存储结果将限制几种情况下的功能。
所以,我认为结果是一个观点细节 - 或者正如James K. Nelson所说的那样,&#34;控制状态&#34; (阅读:The 5 Types of React Application State)。您的问题并未说明您正在使用哪个视图库(如果有),但无论您是否使用React,此处的概念都应适用。
搜索结果应由视图计算。视图将接收用户输入,可能获取数据(将添加到存储中),在Redux状态下运行一些过滤器功能,并显示结果。
答案 2 :(得分:0)
如果您能够重复使用搜索结果,意味着搜索查询相同或跨组件共享,那么最好使用共享组件。如果不是,建议将搜索和搜索结果分开并与上下文相关。
参见唐与他的todos样本分享的例子。他为所有Todos ,已完成Todos 和 Active Todos 创建了三个不同的列表。
答案 3 :(得分:0)
我认为答案取决于你的需要:
如果你想通过第一种情况进行自动转发,我建议将所有搜索数组合起来,并将数据存储在提供更多deatils的对象中,例如searchContext等。 如果您希望通过第二种情况自动完成,则其他上下文的搜索结果不相关,因此建议对任何搜索上下文使用单独的数组。