应该使用Relay将状态置于嵌套表单组件UI中的哪个位置?

时间:2016-04-23 07:16:08

标签: reactjs relayjs

我有一个基本上是表单的UI,但它有不同的组件来编辑特定的数据。当用户单击“保存”按钮时,我希望同时保存页面上的所有数据。所有数据都包含在一个类型中,并且我有该类型的更新变异。因此,虽然不同的子组件可能正在编辑将要保存的对象的不同部分,但是父组件将负责执行保存所有数据的单个更新突变。

我遇到的问题是我不知道我应该在哪里拥有子组件的状态。无论如何,似乎它们的状态必须在父级中,以便它具有它并且可以将它包含在它执行它时传递​​给突变的输入对象中。然而,这些让我处于两个地方之一,这似乎都不理想:

  1. 仅存储父组件中子组件正在编辑的值的状态。
    • 问题:Relay抛出警告,因为我将状态对象传递给子RelayContainer,当它期望它是Relay提取的片段时。您可以在this playground中看到此警告和此行为的示例。以下是我在编辑子组件中的字段时所看到的具体警告。
        

      警告:RelayContainer:提供给details的预期道具[object Object]是Relay提取的数据。除非您故意传递符合此组件片段形状的模拟数据,否则这可能是错误。

  2. 让子组件保持自己的状态,然后将值传递给父组件,以便它们具有处理保存操作和执行突变的目的。
    • 问题:重复状态。尽管父母中的状态仅仅是为了执行突变而被保留,但是将其存在并且将导致父母不必要的渲染似乎是错误的。您可以在此other playground中看到此变体的示例。
  3. 希望有一种明显的首选方式来处理这种情况,但是从我的搜索和玩Relay我无法确定它。

1 个答案:

答案 0 :(得分:3)

首先要做的事情。写得很好的问题。谢谢: - )

React和Relay世界中使用的常见模式是我们有一个父组件,它扮演一个瘦视图控制器,使用Relay获取数据并将其state的不同部分传递给{{1}根据需要使用不同的子组件。接收数据为props的子组件通常是愚蠢的,只显示传递的数据。

在您的情况下,props本身会编辑数据。它确实从其父组件ChildComponent接收初始details数据。但是,当我们编辑UI中的任何HelloApp字段时,details提取的值与UI中的值不匹配。在为子组件创建Relay容器时,如果我们包含片段和字段,我们声明这些数据将由Relay提取。现在,如果我们想要修改子组件' data(props)我们只是跳过Relay容器中的那个片段。父组件传递的Relay将仅用于子组件的props

必要的更改位于initialState容器中。 HelloApp的字段从子节点移动到父节点。

details

但是我仍然对上述解决方案感到不舒服。因为它清楚地表明,父母必须知道HelloApp = Relay.createContainer(HelloApp, { fragments: { person: () => Relay.QL` fragment on Person { name, details { hairColor, nickName } } `, } }); 的字段,这些字段实际上用于子组件。