使用 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 中看到此警告和此行为的示例。这是我指的是您在编辑子组件中的字段时看到的特定警告。

    警告:RelayContainer:提供给 [object Object] 的预期道具 details 将由 Relay 获取数据。除非您有意传入符合该组件片段形状的模拟数据,否则这很可能是一个错误。

    让子组件保持它们自己的状态,但随后也将值传递给父组件,以便它拥有它们以用于处理保存操作和执行突变。 问题:状态重复。尽管父级中的状态只是为了执行突变而保留,但将其保留在那里似乎是非常错误的,并且会导致父级不必要的渲染。您可以在 other playground 中看到这种变化的示例。

希望有一种明显的首选方法来处理这种情况,但是从我四处寻找和玩 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 查询结果中提取深度嵌套的节点吗?

嵌套的 React/Relay 组件不接收道具

使用 Relay.setVariables 保留 React 组件状态

Element-ui中 表单(Form)校验的几种形式 及 表单嵌套表格含上传(Upload)组件的

Element-ui中 表单(Form)校验的几种形式 及 表单嵌套表格含上传(Upload)组件的综合案例

如何使用“文本输入”以“状态”更改和保存嵌套数据