我可以从 Relay 查询结果中提取深度嵌套的节点吗?
Posted
技术标签:
【中文标题】我可以从 Relay 查询结果中提取深度嵌套的节点吗?【英文标题】:Can I pull deeply-nested nodes from a Relay query result? 【发布时间】:2017-05-22 06:10:32 【问题描述】:我的目标是将同一个 Relay fragment
中的多个嵌套同级 arrays
和 edges
组合成一个 render
调用。
后端数据通过Relay
容器传递(也使用react-router-relay
)。
我有一个组件层次结构,它显示来自多个不同Users
的多个Tags
。***查询如下所示:
getUserGroup(id: 'abc')
users
edges // array of arrays objects with nested arrays
node
Tags
edges // array of objects with target items
node
tagName // target item
id
这会导致这样的结果(完全扁平化的形式):
results = [['tagname1', 'tagname2'], [tagname3, tagname4]]
目前,我在自己的Component
中呈现每个node Type
的层次结构,即Tagmenu
-> UserTagGroup
-> TagItems
(代码在这篇文章的底部)。
这会将所有标签按User
分组,最终呈现如下列表:
User 1:
- Tag 1
- Tag 2
User 2:
- Tag 3
- Tag 4
我想要实现的是render
,其中所有Users
'标签在第二层混合在一起,即像TagMenu
这样的层次结构@ -> TagItems
,以呈现:
User Tags
- Tag 1
...
- Tag 4
到目前为止,我能管理的唯一方法是手动从*** Relay
容器结果中提取所有数组并将其与类似这样的内容(伪代码)组合:
for each array in users.edges:
for each array in node.Tags.edges:
return node.tagName
这似乎不正确,原因有两个:
-
打包到
render()
函数中有点多,
不清楚是否可以to protect against null
refs with default props
in Relay
...但这显然是可行的。
我的问题是:Relay
的方法是什么?考虑到库如何自然地导致组件组合,我无法想象在更高级别拉深嵌套的结果并手动改组它们是最佳的。这是我的组件:
// TagsMenu component, top level
class TagsMenu extends Component
render()
return (
<div>
this.props.userGroup.users.edges.map(u =>
return <UserTagGroup user=u.node />
)
</div>
)
fragment on UserGroup
users(first: 1000)
edges
node
$UserTagGroup.getFragment('user')
// UserTagGroup, second component
class UserTagGroup extends Component
render()
return (
<div>
<h4>User: this.props.user.id</h4>
this.props.user.Tags.edges.map(t =>
return <TagMenuItem tag=t.node />
)
</div>
)
fragment on User
id
listingTags(first: 1000)
edges
node
$TagMenuItem.getFragment('tag')
// TagMenuItem, bottom level component. Renders 1 Tag.
class TagMenuItem extends Component
render()
return (
<div>
this.props.tag.tagName
</div>
)
fragment on Tag
tagName
id
【问题讨论】:
【参考方案1】:您一直在描述的内容 - “手动从*** Relay 容器中提取和组合所有数组” - 不过看起来确实是可行的方法。
如果问题出在render()
方法中有这个功能,我建议你结合使用状态和方法componentWillReceiveProps()
。目标是仅在 this.props.users
真正改变时重新计算扁平化列表。
沿着这些路线的东西:
class MyRootContainer extends Component
constructor(props)
super(props);
this.state =
flattenedList: this.computeFlattenedListFromProps(this.props),
;
componentWillReceiveProps(props)
if (this.props.users !== props.users)
this.setState(
flattenedList: this.computeFlattenedListFromProps(props),
);
computeFlattenedListFromProps(props)
// Compute and return flattened list
render()
...
【讨论】:
以上是关于我可以从 Relay 查询结果中提取深度嵌套的节点吗?的主要内容,如果未能解决你的问题,请参考以下文章
MongoDB Mongoose 聚合查询深度嵌套数组删除空结果并填充引用