中继 QueryRenderer fragmentContainer 传递的道具与服务器响应不同,因为 id 冲突
Posted
技术标签:
【中文标题】中继 QueryRenderer fragmentContainer 传递的道具与服务器响应不同,因为 id 冲突【英文标题】:Relay QueryRenderer fragmentContainer passed props different from server response because id conflict 【发布时间】:2018-02-17 02:55:43 【问题描述】:我遇到了这个奇怪的问题,基本上:
-
来自
QueryRenderer
的graphql 请求
从服务器返回的响应包含数据(从开发工具中的“网络”选项卡检查)
props
填充在 QueryRenderer
render( error, props )
函数中
props
被传递到子组件中,createFragmentContainer
呈现值
一个字段的呈现值与响应不同
我不确定中继在从自己的存储中查找数据时在做什么,但我怀疑这是因为在类型中缺少id
声明,以下是代码示例:
App.js
<QueryRenderer
environment=env
query=graphql`
query ScoreboardContainerQuery($ID: ID!)
scoreboard(id: $ID)
...Scoreboard_scoreboard
`
variables=ID: gameID
render=( error, props ) =>
return <Scoreboard scoreboard=props ? props.scoreboard : undefined />
/>
Scoreboard.js
const Scoreboard = ( scoreboard ) => (
<main>
scoreboard.matches.map(match => <Match key=match.id match=match />)
</main>
)
export default createFragmentContainer(Scoreboard,
scoreboard: graphql`
fragment Scoreboard_scoreboard on FootballScoreboard
matches
...Match_match
`,
)
Match.js
const Match = ( match ) => (
<div>
<div>
match.homeTeam.displayName-
match.homeTeam.score
</div>
<div>
match.awayTeam.displayName-
match.awayTeam.score
</div>
</div>
)
export default createFragmentContainer(Match,
match: graphql`
fragment Match_match on Match
date
homeTeam // this is a Team type
id
displayName
score
awayTeam // this is a Team type
id
displayName
score
`,
)
来自服务器的matches
响应示例:
matches = [
"date": "2017-09-03T06:00:00Z",
"homeTeam":
"id": "330",
"displayName": "STG",
"score": "20"
,
"awayTeam":
"id": "332",
"displayName": "CBY",
"score": "0"
,
"date": "2017-08-27T06:00:00Z",
"homeTeam":
"id": "329",
"displayName": "PEN",
"score": "14"
,
"awayTeam":
"id": "330",
"displayName": "STG",
"score": "0"
,
"date": "2017-08-12T05:00:00Z",
"homeTeam":
"id": "330",
"displayName": "STG",
"score": "42"
,
"awayTeam":
"id": "337",
"displayName": "GCT",
"score": "0"
,
]
渲染值:
(
<main>
<div>
<div>STG-42</div>
<div>CBY-6</div>
</div>
<div>
<div>PEN-0</div>
<div>STG-42</div>
</div>
<div>
<div>STG-42</div>
<div>GCT-18</div>
</div>
</main>
)
所以所有STG
值都被覆盖为42,它不应该被覆盖。
这个问题是因为Match
类型中没有id
响应是一个数组引起的吗?
这就是为什么中继正在寻找具有相同 ID 的 Team
?
【问题讨论】:
【参考方案1】:发生这种情况是因为 Relay 每次都会更新 Team
类型的 id 330
(即 SGT),并使用最新的值;最后一个是 42。
您可以从Team
中删除score
字段(这似乎有点奇怪,一个团队没有一个 得分;在一场比赛中,她有一个score),并在 Match
类型上创建 2 个字段:awayTeamScore
和 homeTeamScore
。
【讨论】:
是的,relay 需要为每种类型提供唯一 ID,因此最终为 teamID 和 matchID 创建了唯一 ID @andiwin 你是说homeTeam
和awayTeam
中的id
现在依赖于比赛ID,认为它是一个团队类型吗?以上是关于中继 QueryRenderer fragmentContainer 传递的道具与服务器响应不同,因为 id 冲突的主要内容,如果未能解决你的问题,请参考以下文章
中继:在 Fragment 中使用常量而不是 graphql`...`
如何将自定义道具传递给 QueryRenderer 渲染函数?
Android中继承AppCompatActivity和直接继承Activity有啥区别呢