使用 Relay 的嵌套表单组件 UI 中的状态应该在哪里?
Posted
技术标签:
【中文标题】使用 Relay 的嵌套表单组件 UI 中的状态应该在哪里?【英文标题】:Where should state live in nested form component UI using Relay? 【发布时间】:2016-08-16 21:55:50 【问题描述】:我的 UI 基本上是一个表单,但它具有用于编辑特定数据的不同组件。当用户单击保存按钮时,我希望同时保存页面上的所有数据。所有数据都包含在一个类型中,并且我有该类型的更新突变。因此,虽然不同的子组件可能正在编辑将要保存的对象的不同部分,但父组件将负责执行保存所有数据的单个更新突变。
我遇到的问题是我不确定子组件的状态应该在哪里。无论如何,它们的状态似乎必须在父级中,以便它拥有它并可以将其包含在输入对象中,当它执行它时它传递给突变。然而,这些让我处于两个地方之一,看起来都不理想:
-
仅将子组件正在编辑的值的状态存储在父组件中。
问题:Relay 引发警告,因为我将状态对象传递给子 RelayContainer,而它期望它是 Relay 获取的片段。您可以在this playground 中看到此警告和此行为的示例。这是我指的是您在编辑子组件中的字段时看到的特定警告。
让子组件保持它们自己的状态,但随后也将值传递给父组件,以便它拥有它们以用于处理保存操作和执行突变。 问题:状态重复。尽管父级中的状态只是为了执行突变而保留,但将其保留在那里似乎是非常错误的,并且会导致父级不必要的渲染。您可以在 other playground 中看到这种变化的示例。警告:RelayContainer:提供给
[object Object]
的预期道具details
将由 Relay 获取数据。除非您有意传入符合该组件片段形状的模拟数据,否则这很可能是一个错误。
希望有一种明显的首选方法来处理这种情况,但是从我四处寻找和玩 Relay 的过程中我无法确定它。
【问题讨论】:
【参考方案1】:首先要做的事情。写得很好的问题。谢谢你:-)
在 React 和 Relay 世界中使用的常见模式是,我们有一个父组件,它充当瘦视图控制器,使用 Relay 获取数据并根据需要将其state
的不同部分作为props
传递给不同的子组件.以props
接收数据的子组件通常是哑的,只显示传递的数据。
在您的情况下,ChildComponent
本身会编辑数据。它确实从其父组件HelloApp
接收初始details
数据。但是,当我们在 UI 中编辑任何 details
字段时,Relay
获取的值与 UI 中的值不匹配。在为子组件创建 Relay 容器时,如果我们包含片段和字段,我们声明这些数据将由 Relay 获取。现在,如果我们想自己修改子组件的数据(props),我们只需跳过中继容器中的那个片段。父组件传递的props
将仅用于initialState
子组件。
必要的更改位于HelloApp
容器中。 details
的字段从子项移动到父项。
HelloApp = Relay.createContainer(HelloApp,
fragments:
person: () => Relay.QL`
fragment on Person
name,
details
hairColor,
nickName
`,
);
但是我仍然对上述解决方案感到不舒服。因为它清楚地表明,父组件必须知道details
的字段,这些字段实际上是在子组件中使用的。
【讨论】:
以上是关于使用 Relay 的嵌套表单组件 UI 中的状态应该在哪里?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Relay.setVariables 保留 React 组件状态
Element-ui中 表单(Form)校验的几种形式 及 表单嵌套表格含上传(Upload)组件的