gpt4 book ai didi

javascript - Redux/Java:管理标准化数据和每个实体的多个模型表示

转载 作者:行者123 更新时间:2023-12-03 13:12:23 25 4
gpt4 key购买 nike

我们正在使用React / Redux构建一个新的应用程序,它是在服务器端渲染的。

我们希望遵循Redux的最佳实践,并在将服务器上的数据传递到商店的初始状态之前对其进行规范化。

对于此示例,假设我们有一个通用的“产品”实体,该实体可能非常复杂,并且在商店的根目录上进行了规范化,而页面级别的状态在商店的根目录下的另一个对象中进行了规范化。因此,结构和 reducer 遵循典型的“ slice reducer ”模式,如下所示:

{
page_x_state: PageReducer
products: ProductsReducer
}

我们正在使用组合归约器将归约器合并,然后再将它们传递到商店中。

Theoretical use case: We have a 'products' page that shows a list of basic product info. A user can click on a product to show a modal which then loads and shows the complete product data.



对于上面的示例,从服务器发送的状态将仅包含基本产品模型(3或4个字段),这足以呈现表,并且此时获取所有产品信息是浪费的,性能也不是很好。

当用户单击产品时,我们将进行AJAX调用以获取该产品的所有数据。一旦获得了单个产品的所有数据,是否应该使用完整模型更新产品存储中的实例?如果是这样,我们将最终得到一组对象,所有对象可能是不同的状态(有些对象可能具有最小的字段,而有些对象是具有10个字段的成熟对象)。这是处理它的最佳方法吗?

另外,我想听听有关在服务器上管理同一基础模型的不同表示形式以及如何将其映射到Redux存储(理想情况下为Java)的任何想法。

最佳答案

编辑:

明确回答您的第一个问题,如果您的reducer构建正确,则整个状态树应该在其中绝对没有数据的情况下进行初始化。但是应该是正确的形状。还原器应始终具有默认返回值-呈现服务器端时-Redux should only render the initial state

在服务器端渲染之后,当商店(即现在的客户端)由于用户操作而需要更新时,所有产品数据的状态形状就已经存在(只是其中一些可能是默认值)。 。可以说,您只需填充空白,而不是覆盖对象。

可以说,在您的第二层 View 中,您需要namephoto_urlpricebrand,并且初始 View 上有4种产品,您呈现的商店将如下所示:

{
products: {
by_id: {
"1": {
id: "1",
name: "Cool Product",
tags: [],
brand: "Nike",
price: 1.99,
photo_url: "http://url.com",
category: "",
product_state: 0,
is_fetching: 0,
etc: ""
},
"2": {
id: "2",
name: "Another Cool Product",
tags: [],
brand: "Adidas",
price: 3.99,
photo_url: "http://url2.com",
category: "",
product_state: 0,
is_fetching: 0,
etc: ""
},
"3": {
id: "3",
name: "Crappy Product",
tags: [],
brand: "Badidas",
price: 0.99,
photo_url: "http://urlbad.com",
category: "",
product_state: 0,
is_fetching: 0,
etc: ""
},
"4": {
id: "4",
name: "Expensive product",
tags: [],
brand: "Rolex",
price: 199.99,
photo_url: "http://url4.com",
category: "",
product_state: 0,
is_fetching: 0,
etc: ""
}
},
all_ids: ["1", "2", "3", "4"]
}
}

您可以在上面的数据中看到某些键只是空字符串或空数组。但是我们拥有我们所需的数据,用于页面的实际初始呈现。

然后,我们可以在渲染服务器并准备好文档后立即在后台在客户端上进行异步调用,很有可能服务器会在用户尝试获取数据之前返回这些初始调用。然后,我们可以根据用户要求加载后续产品。我认为这不是 最好的方法,但对我来说最有意义。其他一些人可能还有其他想法。这完全取决于您的应用程序和用例。

不过,我只会将一个产品对象保持在状态中,并将与产品有关的所有数据保留在其中。

I recently deployed an app into production and i'll share some of my insights. The app, whilst not being too large in size, had a complex data structure and having gone through the whole process as a newbie to Redux in production (and having guidance from my architect) – These are some of our takeaways. There's no right way in terms of architecture but there certainly are some things to avoid or do.



1.在编写 reducer 之前,设计一个“静态”状态

如果您不知道要去哪里,那将无法到达那里。将状态的整个结构写得平坦,可以帮助您推断状态将如何随着时间变化。我们发现这节省了我们的时间,因为我们不必真正重写较大的部分。

2.设计状态

把事情简单化。 Redux的全部重点是简化状态管理。我们使用了丹·阿布拉莫夫(Dan Abramov)创建的Redux上 egghead.io tutorials的许多技巧。很明显,它们确实帮助解决了我们遇到的许多问题。我确定您已经对normalt state进行了 read the docs讨论,但是他们给出的简单示例实际上已在我们实现的大多数数据模式中进行了介绍。

与其创建复杂的数据 网,不是每个数据块仅保存其自己的数据(如果它需要引用另一条数据 )(仅由id 引用),我们发现这种简单的模式可以满足我们的大部分需求。
{
products: {
by_id: {
"1": {
id: "1",
name: "Cool Product",
tags: ["tag1", "tag2"],
product_state: 0,
is_fetching: 0,
etc: "etc"
}
},
all_ids: ["1"]
}
}

在上面的示例中,标记可能是使用 by_idall_ids具有类似数据结构的另一数据块。 在整个文档和tut中,Abramov不断引用关系数据和关系数据库,这实际上是我们的关键。首先,我们一直在关注UI并围绕我们认为如何展示它的状态来设计状态。单击此按钮,然后我们开始根据数据与其他数据的关系对数据进行分组,事情就此开始发生。

迅速转到您的问题,我将避免重复任何数据,如另一条评论中所述,我个人只是在状态对象 product_modal中创建一个键。让模态照顾自己的状态...
{
products: {
...
},
product_modal: {
current_product_id: "1",
is_fetching: true,
is_open: true
}
}

我们发现遵循此模式的页面状态确实很好用...我们只是将其像其他具有id / name等的数据一样对待。

3. reducer 逻辑

make sure reducers keep track of their own state。我们的许多reducer看起来都非常相似,起初感觉就像DRY hell ,但是后来我们很快意识到更多reducer的强大功能。。。比如说调度了一个 Action ,并且您想更新整个状态。在 reducer 中执行该操作并返回新状态。如果您只想更新处于相同状态的一个或两个字段...那么您只需要在要更改的字段中做同样的事情即可。我们的大多数化简器只是带有偶尔嵌套的if语句的switch语句。

合并 reducer

我们没有使用CombineReducers,我们编写了自己的。这并不难,它帮助我们了解了Redux的情况,并使我们对自己的状态更加了解。 This tut was invaluable

操作

中间件是您的 friend ...我们将获取API与 redux-thunk一起使用,以发出RESTful请求。我们将所需的数据请求分成单独的操作,对于需要为调用进行更新的每个数据块,这些操作分别调用store.dispatch()。每个调度都调度另一个操作以更新状态。这使我们的状态保持模块化更新,并允许我们根据需要更新大的部分。

处理API

好的,所以这里有太多方法要处理。我并不是说我们的方法是最好的...但是它对我们有用。简而言之...我们在Java中有一个内部API,带有公开暴露的端点。从该API进行的调用并不总是很容易映射到前端。我们尚未实现此功能,但理想情况下,可以在其末端写入初始 init端点,以获取大量初始数据,这些数据是为了使速度在前端运行而需要的。

我们在与该应用程序相同的服务器上用PHP编写了一个公共(public)API。该API从前端和浏览器中提取了内部API的终结点(在某些情况下还包括数据)。

当应用发出GET请求以 /api/projects/all的请求时,PHP API将调用我们的内部API,获取必要的数据(有时需要几个请求),然后以Redux可以消耗的可用格式返回该数据。

对于Javascript应用程序来说,这可能不是理想的方法,但是我们没有选择创建新的内部API结构的方法,我们需要使用已经存在几年的结构,我们发现其性能可以接受。

关于javascript - Redux/Java:管理标准化数据和每个实体的多个模型表示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47356671/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com