在 Relay Modern 中使用订阅时,`updater` 无法正常工作
`updater` not working correctly when using subscriptions in Relay Modern
我在我的应用程序中使用 Relay Modern,并使用 requestSubscription
函数成功集成了订阅。一切正常,我用来更新缓存的 updater
函数可以使用正确的订阅负载正确调用。
订阅用于将新项目添加到 Link
元素列表中。这是订阅的样子:
NewLinkSubscription.js
const newLinkSubscription = graphql`
subscription NewLinkSubscription {
Link {
mutation
node {
id
description
url
createdAt
postedBy {
id
name
}
}
}
}
`
export default (updater, onError) => {
const subscriptionConfig = {
subscription: newLinkSubscription,
variables: {},
updater,
onError
}
requestSubscription(
environment,
subscriptionConfig
)
}
然后我有一个 LinkList
组件来呈现所有 Link
元素。在该组件的 componentDidMount
中,我启动了 NewLinkSubscription
:
LinkList.js
class LinkList extends Component {
componentDidMount() {
NewLinkSubscription(
proxyStore => {
const createLinkField = proxyStore.getRootField('Link')
const newLink = createLinkField.getLinkedRecord('node')
const viewerProxy = proxyStore.get(this.props.viewer.id)
const connection = ConnectionHandler.getConnection(viewerProxy, 'LinkList_allLinks')
if (connection) {
ConnectionHandler.insertEdgeAfter(connection, newLink)
}
},
error => console.log(`An error occured:`, error),
)
}
render() {
console.log(`LinkList - render `, this.props.viewer.allLinks.edges)
return (
<div>
{this.props.viewer.allLinks.edges.map(({node}) =>
{
console.log(`render node: `, node)
return <Link key={node.id} link={node} viewer={this.props.viewer} />
}
)}
</div>
)
}
}
export default createFragmentContainer(LinkList, graphql`
fragment LinkList_viewer on Viewer {
id
...Link_viewer
allLinks(last: 100, orderBy: createdAt_DESC) @connection(key: "LinkList_allLinks", filters: []) {
edges {
node {
...Link_link
}
}
}
}
`)
现在,这是当带有新 Link
的订阅进来时发生的事情。 updater
被正确调用并且新节点似乎被正确插入到连接中(至少 ConnectionHandler.insertEdgeAfter(connection, newLink)
被调用)。
这会触发组件的重新渲染。当我调试 render
以检查数据 (props.viewer.allLinks.edges
) 时,我可以看到一个新节点确实被添加到连接中 - 所以列表现在实际上确实包含了一个项目!然而,问题是这个新节点实际上是 undefined
导致应用程序崩溃!
有没有人发现我在这里遗漏了什么?
我能够让它工作,这就是我现在实施 updater
的方式:
NewLinkSubscription(
proxyStore => {
const linkField = proxyStore.getRootField('Link')
const newLink = linkField.getLinkedRecord('node')
const viewerProxy = proxyStore.get(this.props.viewer.id)
const connection = ConnectionHandler.getConnection(viewerProxy, 'LinkList_allLinks', {
last: 100,
orderBy: 'createdAt_DESC'
})
if (connection) {
const edge = ConnectionHandler.createEdge(proxyStore, connection, newLink, 'allLinks')
ConnectionHandler.insertEdgeBefore(connection, edge)
}
},
error => console.log(`An error occurred:`, error),
)
我在我的应用程序中使用 Relay Modern,并使用 requestSubscription
函数成功集成了订阅。一切正常,我用来更新缓存的 updater
函数可以使用正确的订阅负载正确调用。
订阅用于将新项目添加到 Link
元素列表中。这是订阅的样子:
NewLinkSubscription.js
const newLinkSubscription = graphql`
subscription NewLinkSubscription {
Link {
mutation
node {
id
description
url
createdAt
postedBy {
id
name
}
}
}
}
`
export default (updater, onError) => {
const subscriptionConfig = {
subscription: newLinkSubscription,
variables: {},
updater,
onError
}
requestSubscription(
environment,
subscriptionConfig
)
}
然后我有一个 LinkList
组件来呈现所有 Link
元素。在该组件的 componentDidMount
中,我启动了 NewLinkSubscription
:
LinkList.js
class LinkList extends Component {
componentDidMount() {
NewLinkSubscription(
proxyStore => {
const createLinkField = proxyStore.getRootField('Link')
const newLink = createLinkField.getLinkedRecord('node')
const viewerProxy = proxyStore.get(this.props.viewer.id)
const connection = ConnectionHandler.getConnection(viewerProxy, 'LinkList_allLinks')
if (connection) {
ConnectionHandler.insertEdgeAfter(connection, newLink)
}
},
error => console.log(`An error occured:`, error),
)
}
render() {
console.log(`LinkList - render `, this.props.viewer.allLinks.edges)
return (
<div>
{this.props.viewer.allLinks.edges.map(({node}) =>
{
console.log(`render node: `, node)
return <Link key={node.id} link={node} viewer={this.props.viewer} />
}
)}
</div>
)
}
}
export default createFragmentContainer(LinkList, graphql`
fragment LinkList_viewer on Viewer {
id
...Link_viewer
allLinks(last: 100, orderBy: createdAt_DESC) @connection(key: "LinkList_allLinks", filters: []) {
edges {
node {
...Link_link
}
}
}
}
`)
现在,这是当带有新 Link
的订阅进来时发生的事情。 updater
被正确调用并且新节点似乎被正确插入到连接中(至少 ConnectionHandler.insertEdgeAfter(connection, newLink)
被调用)。
这会触发组件的重新渲染。当我调试 render
以检查数据 (props.viewer.allLinks.edges
) 时,我可以看到一个新节点确实被添加到连接中 - 所以列表现在实际上确实包含了一个项目!然而,问题是这个新节点实际上是 undefined
导致应用程序崩溃!
有没有人发现我在这里遗漏了什么?
我能够让它工作,这就是我现在实施 updater
的方式:
NewLinkSubscription(
proxyStore => {
const linkField = proxyStore.getRootField('Link')
const newLink = linkField.getLinkedRecord('node')
const viewerProxy = proxyStore.get(this.props.viewer.id)
const connection = ConnectionHandler.getConnection(viewerProxy, 'LinkList_allLinks', {
last: 100,
orderBy: 'createdAt_DESC'
})
if (connection) {
const edge = ConnectionHandler.createEdge(proxyStore, connection, newLink, 'allLinks')
ConnectionHandler.insertEdgeBefore(connection, edge)
}
},
error => console.log(`An error occurred:`, error),
)