reactjs - 我怎样才能拥有同一个顶级片段容器的多个兄弟实例?

标签 reactjs relay relaymodern

我正在遵循本指南:https://relay.dev/docs/en/quick-start-guide#composing-fragments

我正在尝试创建一个更高级别的片段容器来查询来自 RootQuery 的数据:

export const FormInstanceListContainer: FunctionComponent<Props> = props => {
  const { data, ...rest } = props
  const { formInstances } = data

  return (
    <FormInstanceList
      formInstances={formInstances}
      {...rest} // Forward all the other props
    />
  )
}

export default createFragmentContainer(FormInstanceListContainer, {
  data: graphql`
    fragment FormInstanceListContainer_data on RootQuery
      @argumentDefinitions(status: { type: "FormStatus" }) {
      formInstances(status: $status) {
        id
        form {
          id
          name
        }
        status
        createdAt
        submittedAt
      }
    }
  `,
})

只要我只需要呈现这些列表之一,它就可以正常工作。这是一个用法示例:

const IndexPage: NextPage<QueryResponse> = data => {
  const handleOpenClick = (formInstance: FormInstance) => {
    NextRouter.push(`/form-instance/${formInstance.uuid}`)
  }

  const handleEditClick = (formInstance: FormInstance) => {
    NextRouter.push(`/form-instance/${formInstance.uuid}/edit`)
  }

  return (
    <DefaultLayout>
      <Container maxWidth="md">
        <Typography variant="h5" style={{ marginBottom: 25 }}>
          My drafts
        </Typography>

        <FormInstanceListContainer
          data={data}
          onOpenClick={handleOpenClick}
          onEditClick={handleEditClick}
        />
      </Container>
    </DefaultLayout>
  )
}

export default withData<pages_dashboard_Query>(IndexPage, {
  query: graphql`
    query pages_dashboard_Query {
      ...FormInstanceListContainer_data @arguments(status: DRAFT)
    }
  `,
})

不幸的是,我需要并排呈现这些列表中的 2 个...一个用于草稿表单,一个用于提交的表单。

我不能只包含再次展开相同的片段:

    query pages_dashboard_Query {
      ...FormInstanceListContainer_data @arguments(status: DRAFT)
      ...FormInstanceListContainer_data @arguments(status: SUBMITTED)
    }

ERROR: Expected all fields on the same parent with the name or alias 'formInstances' to have the same name and arguments.

那么如何在同一页面上拥有多个具有不同数据的 FormInstanceListContainer 呢?我设计片段容器的方式是否走入了死胡同?


如果我能够在顶级页面中运行查询(从那时起我可以使用别名)并将结果列表传递给 FormInstanceListContainer,问题就会得到解决。为此,在我看来 FormInstanceListContainer 必须请求查询的字段而不是查询本身:

export default createFragmentContainer(FormInstanceListContainer, {
  formInstance: graphql`
    fragment FormInstanceListContainer_formInstance on FormInstance {
      id
      form {
        id
        name
      }
      status
      createdAt
      submittedAt
    }
  `,
})

但是,现在 Relay 假设应该将 FormInstance单个实例传递给容器,而不是它们的列表。我尝试传递列表的任何方式都会导致 Relay 崩溃。是否可以指示 Relay 它应该期望值列表而不是单个值?

我完全卡住了。

最佳答案

我想我遇到过这个问题,我想我按照你的建议解决了它,方法是在查询中包含需要别名的字段:

graphql`
   fragment FormInstanceFields on FormInstance {
      id
      form {
        id
        name
      }
      status
      createdAt
      submittedAt
   }
`
export default withData<pages_dashboard_Query>(IndexPage, {
  query: graphql`
    query pages_dashboard_Query {
      drafts: formInstances(status: DRAFT) {
        ...FormInstanceFields
      }
      submitted: formInstances(status: SUBMITTED) {
        ...FormInstanceFields
      }
    }
  `,
})

(以上片段需要根据编译器要求正确命名)

那么要做的就是FormInstanceList 包装在片段容器中,因为正如您所指出的那样,这会导致错误。包装它的冲动很强烈,因为使用基于 HOC 的 API,本能是通过渲染树一路向下包装。但这在这种情况下不起作用。

相反,将每个 FormInstance 包装在一个片段容器中(我猜您已经在这样做了)。然后它会起作用。 draftssubmitted 字段将包含中继存储引用的数组,您可以对它们进行交互并将每个传递给 FormInstanceContainer

这可能感觉不对,但是如果你从即将推出的hooks API的角度来想,还是relay-hooks , 真的没有错。


编辑

有一段时间没有使用 Relay,但我认为您甚至可以通过执行以下操作来保留所有级别的容器:

graphql`
  fragment FormInstanceListContainer_data on RootQuery {
      drafts: formInstances(status: DRAFT) {
        ...FormInstanceFields
      }
      submitted: formInstances(status: SUBMITTED) {
        ...FormInstanceFields
      }
  }
`

那不应该也行吗?

关于reactjs - 我怎样才能拥有同一个顶级片段容器的多个兄弟实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63854838/

相关文章:

javascript - 类型错误 : Object(…) is not a function

reactjs - 中继片段传播不起作用

javascript - 使用 RelayJS 中的数据通过 React JS 过滤名称列表,而不调用 GraphQL

reactjs - 如何使用 react-query 获取 n 个依赖数据

javascript - ReactJS动态路由没有 "/"

javascript - Graphql,react-apollo 如何在加载组件状态时将变量传递给查询

javascript - 如何处理 Relay Modern 上的突变错误?

javascript - 中继 createFragmentContainer 的现代用途

javascript - 中继现代突变,RANGE_ADD/Append

reactjs - 继电器现代: delete record in optimisticUpdater