ReactJS - 道具与状态 + 商店设计

ReactJS - props vs state + Store designing

想象一下: 您正在编写一个 'smart-house' 应用程序来管理您家中的温度。

在我看来我想:

有一个外部设备,通过 websockets 与您的应用程序通信(它会定期发送当前温度、空调状态)。

我看到两个选项:

1) 创建一个 'big' 存储包含如下数据结构:

var _data = [
   name: 'Kitchen',
   currentTemperature: 25,
   desiredTemperature: 22,
   sensors: [
       {
           name: 'Air Conditioning'
           state: 'on'
       }
       ... there might be other sensors too ...
   ]
]

会有一个 TemperatureManager 组件(或类似的东西)。它会有一个状态并定期从 Store 中获取它。 然后它会将状态的一部分分发给他的后代(即RoomTemperatureManager,RoomSystemSensorManager),将其作为道具传递。

如果有任何变化(例如,卧室的温度),它将从存储中获取所有数据并在必要时重新渲染其后代。

2)第二种方案是

RoomTemperatureManagersRoomSystemSensorManagers 有自己的状态。它还与温度和 SystemSensorState 的独立存储有关。

这些 Store 将使用参数化的 getter(即 getSensorState(roomName))而不是方法来获取所有数据。

问题:

哪个选项更好?

补充问题:

叶子组件(即负责管理所需温度的组件)直接调用ActionCreator 可以吗?或者也许只有监督组件应该知道关于 ActionCreator 的任何事情并且应该将适当的方法作为 属性 传递给他的后代?

我认为最好的方法是授权。您的 TemperatureManager 应该有一种机制来通知侦听器有更新,而 Room(Temperature|System)Manager 将作为listener 一个回调,它将使用更新的数据并相应地更改状态。这将利用虚拟 DOM diff,因此仅显示更改,而不是重新渲染整个部分,并创建一个可以与商店通信的单点。 Room(Temperature|System)Manager 应仅在需要对正在使用的模型进行更新时才与 Store 通信。

TemperatureManager 如果在订阅时可以改进,您可以指定要收听哪些数据以进行更新。它不应该假定特定的 'manager' 应该获得数据的任何子集。

您在 post 中描述的 2 个选项实际上是 2 个不同的问题:

  1. 一家大店还是几家不同的店?
  2. 子组件 (RoomTemperatureManagers) 应该有自己的状态还是从商店接收道具?

Ad 1. 只要不复杂,一个大商店就容易多了。我使用的经验法则:如果您的商店有 > 300 行代码,最好分开在不同的商店。

广告 2. 道具通常比状态好。但在你的情况下,我认为你需要状态,例如你的温度管理器:你在你的应用程序中设置温度(并希望看到它反映在一些滑块或其他东西中)。为此,您将需要状态。

  • 状态立即更新前端(乐观更新)。
  • 然后该组件将 set_temparature 动作发送到 屋。
  • 然后房子里的传感器确认它已经设置了新的 温度到您的应用程序。
  • 商店更新并发出零钱。
  • 房屋中传感器的温度设置传达为 道具给你的温度管理器。
  • Temperature 管理器会做任何它需要做的事情(简单地用新的属性更新状态,显示确认消息,或者如果通信链出现故障,则显示漂亮的错误消息)。